Skip to content

Commit

Permalink
lib: lte_link_control: refactor into modules
Browse files Browse the repository at this point in the history
Divides the LTE Link Controller into modules.

Signed-off-by: Mirko Covizzi <mirko.covizzi@nordicsemi.no>
  • Loading branch information
MirkoCovizzi committed Sep 20, 2024
1 parent 6b91503 commit 6c7a95e
Show file tree
Hide file tree
Showing 48 changed files with 4,216 additions and 3,530 deletions.
1 change: 1 addition & 0 deletions applications/asset_tracker_v2/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ CONFIG_LTE_PSM_REQ=y
CONFIG_LTE_PSM_REQ_RPTAU="11000001"
### 20 seconds active time.
CONFIG_LTE_PSM_REQ_RAT="00001010"
CONFIG_LTE_LC_NCELLMEAS=y

# Settings - Used to store real-time device configuration to flash.
CONFIG_SETTINGS=y
Expand Down
5 changes: 4 additions & 1 deletion lib/lte_link_control/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
#

zephyr_library()
zephyr_library_include_directories(include)
zephyr_library_sources(lte_lc.c)
zephyr_library_sources(lte_lc_helpers.c)
zephyr_library_sources(lte_lc_modem_hooks.c)
zephyr_library_sources_ifdef(CONFIG_LTE_LC_TRACE lte_lc_trace.c)
zephyr_library_sources_ifdef(CONFIG_LTE_SHELL lte_lc_shell.c)

add_subdirectory(common)
add_subdirectory(modules)

zephyr_linker_sources(RODATA lte_lc.ld)
4 changes: 4 additions & 0 deletions lib/lte_link_control/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ config LTE_PSM_REQ
If this option is set the library will automatically request PSM when
the modem is initialized. This will cause the modem to include a PSM request in
every subsequent LTE attach request.
select LTE_LC_PSM

choice LTE_PSM_REQ_FORMAT
prompt "Format for PSM configuration"
Expand Down Expand Up @@ -129,6 +130,7 @@ config LTE_EDRX_REQ
help
Enable request for use of eDRX using AT+CEDRXS.
For reference, see 3GPP 27.007 Ch. 7.40.
select LTE_LC_EDRX

config LTE_EDRX_REQ_VALUE_LTE_M
string "Requested eDRX value for LTE-M"
Expand Down Expand Up @@ -354,4 +356,6 @@ module-dep = LOG
module-str = LTE link control library
source "${ZEPHYR_BASE}/subsys/logging/Kconfig.template.log_config"

rsource "modules/Kconfig"

endif # LTE_LINK_CONTROL
8 changes: 8 additions & 0 deletions lib/lte_link_control/common/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#
# Copyright (c) 2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

zephyr_library_sources(event_handler_list.c)
zephyr_library_sources(work_q.c)
124 changes: 124 additions & 0 deletions lib/lte_link_control/common/event_handler_list.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <string.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <modem/lte_lc.h>

#include <common/event_handler_list.h>

LOG_MODULE_DECLARE(lte_lc, CONFIG_LTE_LINK_CONTROL_LOG_LEVEL);

static K_MUTEX_DEFINE(list_mtx);

/**@brief List element for event handler list. */
struct event_handler {
sys_snode_t node;
lte_lc_evt_handler_t handler;
};

static sys_slist_t handler_list;

/**
* @brief Find the handler from the event handler list.
*
* @return The node or NULL if not found and its previous node in @p prev_out.
*/
static struct event_handler *event_handler_list_node_find(struct event_handler **prev_out,
lte_lc_evt_handler_t handler)
{
struct event_handler *prev = NULL, *curr;

SYS_SLIST_FOR_EACH_CONTAINER(&handler_list, curr, node) {
if (curr->handler == handler) {
*prev_out = prev;
return curr;
}
prev = curr;
}
return NULL;
}

/**@brief Add the handler in the event handler list if not already present. */
int event_handler_list_handler_append(lte_lc_evt_handler_t handler)
{
struct event_handler *to_ins;

k_mutex_lock(&list_mtx, K_FOREVER);

/* Check if handler is already registered. */
if (event_handler_list_node_find(&to_ins, handler) != NULL) {
LOG_DBG("Handler already registered. Nothing to do");
k_mutex_unlock(&list_mtx);
return 0;
}

/* Allocate memory and fill. */
to_ins = (struct event_handler *)k_malloc(sizeof(struct event_handler));
if (to_ins == NULL) {
k_mutex_unlock(&list_mtx);
return -ENOBUFS;
}
memset(to_ins, 0, sizeof(struct event_handler));
to_ins->handler = handler;

/* Insert handler in the list. */
sys_slist_append(&handler_list, &to_ins->node);
k_mutex_unlock(&list_mtx);
return 0;
}

/**@brief Remove the handler from the event handler list if registered. */
int event_handler_list_handler_remove(lte_lc_evt_handler_t handler)
{
struct event_handler *curr, *prev = NULL;

k_mutex_lock(&list_mtx, K_FOREVER);

/* Check if the handler is registered before removing it. */
curr = event_handler_list_node_find(&prev, handler);
if (curr == NULL) {
LOG_WRN("Handler not registered. Nothing to do");
k_mutex_unlock(&list_mtx);
return 0;
}

/* Remove the handler from the list. */
sys_slist_remove(&handler_list, &prev->node, &curr->node);
k_free(curr);

k_mutex_unlock(&list_mtx);
return 0;
}

/**@brief dispatch events. */
void event_handler_list_dispatch(const struct lte_lc_evt *const evt)
{
struct event_handler *curr, *tmp;

if (event_handler_list_is_empty()) {
return;
}

k_mutex_lock(&list_mtx, K_FOREVER);

/* Dispatch events to all registered handlers */
LOG_DBG("Dispatching event: type=%d", evt->type);
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&handler_list, curr, tmp, node) {
LOG_DBG(" - handler=0x%08X", (uint32_t)curr->handler);
curr->handler(evt);
}
LOG_DBG("Done");

k_mutex_unlock(&list_mtx);
}

/**@brief Test if the handler list is empty. */
bool event_handler_list_is_empty(void)
{
return sys_slist_is_empty(&handler_list);
}
30 changes: 30 additions & 0 deletions lib/lte_link_control/common/work_q.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <zephyr/kernel.h>

#include "common/work_q.h"

K_THREAD_STACK_DEFINE(work_q_stack, CONFIG_LTE_LC_WORKQUEUE_STACK_SIZE);

struct k_work_q work_q;

int work_q_start(void)
{
struct k_work_queue_config cfg = {
.name = "work_q",
};

k_work_queue_start(&work_q, work_q_stack, K_THREAD_STACK_SIZEOF(work_q_stack),
K_LOWEST_APPLICATION_THREAD_PRIO, &cfg);

return 0;
}

struct k_work_q *work_q_get(void)
{
return &work_q;
}
50 changes: 50 additions & 0 deletions lib/lte_link_control/include/common/event_handler_list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef EVENT_HANDLER_LIST_H__
#define EVENT_HANDLER_LIST_H__

#include <modem/lte_lc.h>

#ifdef __cplusplus
extern "C" {
#endif

/* @brief Add the handler in the event handler list if not already present.
*
* @param handler Event handler.
*
* @return Zero on success, negative errno code if the API call fails.
*/
int event_handler_list_handler_append(lte_lc_evt_handler_t handler);

/* @brief Remove the handler from the event handler list if present.
*
* @param handler Event handler.
*
* @return Zero on success, negative errno code if the API call fails.
*/
int event_handler_list_handler_remove(lte_lc_evt_handler_t handler);

/* @brief Dispatch events for the registered event handlers.
*
* @param evt Event.
*
* @return Zero on success, negative errno code if the API call fails.
*/
void event_handler_list_dispatch(const struct lte_lc_evt *const evt);

/* @brief Test if the handler list is empty.
*
* @return a boolean, true if it's empty, false otherwise
*/
bool event_handler_list_is_empty(void);

#ifdef __cplusplus
}
#endif

#endif /* EVENT_HANDLER_LIST_H__ */
23 changes: 23 additions & 0 deletions lib/lte_link_control/include/common/work_q.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef WORK_Q_H__
#define WORK_Q_H__

#include <zephyr/kernel.h>

#ifdef __cplusplus
extern "C" {
#endif

int work_q_start(void);
struct k_work_q *work_q_get(void);

#ifdef __cplusplus
}
#endif

#endif /* WORK_Q_H__ */
43 changes: 43 additions & 0 deletions lib/lte_link_control/include/helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef HELPERS_H__
#define HELPERS_H__

#include <string.h>
#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/types.h>

#ifdef __cplusplus
extern "C" {
#endif

static int string_to_int(const char *str_buf, int base, int *output)
{
int temp;
char *end_ptr;

__ASSERT_NO_MSG(str_buf != NULL);

errno = 0;
temp = strtol(str_buf, &end_ptr, base);

if (end_ptr == str_buf || *end_ptr != '\0' ||
((temp == LONG_MAX || temp == LONG_MIN) && errno == ERANGE)) {
return -ENODATA;
}

*output = temp;

return 0;
}

#ifdef __cplusplus
}
#endif

#endif /* HELPERS_H__ */
25 changes: 25 additions & 0 deletions lib/lte_link_control/include/modules/cereg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef CEREG_H__
#define CEREG_H__

#include <modem/lte_lc.h>

#ifdef __cplusplus
extern "C" {
#endif

int cereg_notifications_enable(void);
int cereg_status_get(enum lte_lc_nw_reg_status *status);
int cereg_mode_get(enum lte_lc_lte_mode *mode);
struct k_sem *cereg_link_sem_get(void);

#ifdef __cplusplus
}
#endif

#endif /* CEREG_H__ */
23 changes: 23 additions & 0 deletions lib/lte_link_control/include/modules/cfun.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef CFUN_H__
#define CFUN_H__

#include <modem/lte_lc.h>

#ifdef __cplusplus
extern "C" {
#endif

int cfun_mode_get(enum lte_lc_func_mode *mode);
int cfun_mode_set(enum lte_lc_func_mode mode);

#ifdef __cplusplus
}
#endif

#endif /* CFUN_H__ */
Loading

0 comments on commit 6c7a95e

Please sign in to comment.