The LTE link controller library is a layer above the nRF Modem library and provides functionality to control the LTE link on the nRF91 Series.
To enable the LTE link controller library in your application, enable the following Kconfig:
CONFIG_LTE_LINK_CONTROL=y
KconfigInclude the header file of the LTE link controller library in your source code.
#include <modem/lte_lc.h>
COne advantage to using the LTE link controller library is having a callback function that allows the application to get callbacks from the library, thereby offloading this process.
Define the callback function lte_handler()
.
For this lesson and subsequent exercise, we will use the events LTE_LC_EVT_NW_REG_STATUS
and LTE_LC_EVT_RRC_UPDATE
.
LTE_LC_EVT_NW_REG_STATUS
: This event carries information about the modem’s network registration status, which can tell us if an LTE link has been established.LTE_LC_EVT_RRC_UPDATE
: This event carries information about the RRC mode, and triggers whenever the mode changes.In the function below, we check the registration status of evt->nw_reg_status
of type lte_lc_nw_reg_status
and if the registration status is of type registered home or registered roaming, we log that information. We also log any change to the RRC mode, as either Connected or Idle.
static void lte_handler(const struct lte_lc_evt *const evt)
{
switch (evt->type) {
case LTE_LC_EVT_NW_REG_STATUS:
if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
(evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
break;
}
LOG_INF("Network registration status: %s",
evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ?
"Connected - home network" : "Connected - roaming");
break;
case LTE_LC_EVT_RRC_UPDATE:
LOG_INF("RRC mode: %s", evt->rrc_mode == LTE_LC_RRC_MODE_CONNECTED ?
"Connected" : "Idle");
break;
default:
break;
}
}
CThe documentation for enum lte_lc_evt_type
explains all the event types in the LTE link controller library.
Connect to the LTE network using the function lte_lc_connect_async()
, which has the following signature.
This function takes the callback function lte_handler()
that we defined in the previous step as a parameter.
lte_lc_connect_async(lte_handler);
CTo ensure the application doesn’t proceed with other operations until an LTE connection is established, we will add a semaphore.
Define the semaphore lte_connected
using K_SEM_DEFINE()
.
Since this semaphore will only be taken once, after the LTE connection function is called and given once, when the LTE connection is established, we pass initial_count
0 and count_limit
1.
K_SEM_DEFINE(lte_connected, 0, 1);
CAfter initiating the LTE connection, take the semaphore using k_sem_take()
.
k_sem_take(lte_connected, K_FOREVER);
CTo make sure the application doesn’t proceed until an LTE connection is established, we want to give the semaphore, using k_sem_give()
, in the event handler, after the registration status is confirmed as connected, see line 9 below.
case LTE_LC_EVT_NW_REG_STATUS:
if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
(evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
break;
}
LOG_INF("Network registration status: %s",
evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ?
"Connected - home network" : "Connected - roaming");
k_sem_give(lte_connected);
break;
CEven though we are using a semaphore to make sure the application doesn’t proceed until an LTE connection is established, this is a non-blocking method because the application can still call functions and create threads after lte_lc_connect_async()
(or lte_lc_init_and_connect_async()
) has been called.
The LTE link control library supports power save modes eDRX and PSM.
To enable the functionalities and Konfigs related to eDRX and PSM, the individual modules need to be enabled through the following two Konfigs:
CONFIG_LTE_LC_EDRX_MODULE=y
CONFIG_LTE_LC_PSM_MODULE=y
KconfigThe eDRX and PSM related functions and Kconfigs are automatically included with the library.
The recommended way of enabling power saving features is to use the following Kconfig options
CONFIG_LTE_PSM_REQ=y
CONFIG_LTE_EDRX_REQ=y
KconfigLTE_LC_EVT_PSM_UPDATE
: This event carries information about the PSM parameters provided by the network.LTE_LC_EVT_EDRX_UPDATE
: This event carries information about the eDRX parameters provided by the networkA timer value that is requested by the modem is not necessarily given by the network. The event callbacks LTE_LC_EVT_PSM_UPDATE
and LTE_LC_EVT_EDRX_UPDATE
contain the values that are actually decided by the network.
The following code snippet shows how you can add these events to the callback function to log the values received by the network
case LTE_LC_EVT_PSM_UPDATE:
LOG_INF("PSM parameter update: Periodic TAU: %d s, Active time: %d s",
evt->psm_cfg.tau, evt->psm_cfg.active_time);
if (evt->psm_cfg.active_time == -1){
LOG_ERR("Network rejected PSM parameters. Failed to enable PSM");
}
break;
/* STEP 9.2 - On event eDRX update, print eDRX paramters */
case LTE_LC_EVT_EDRX_UPDATE:
LOG_INF("eDRX parameter update: eDRX: %f, PTW: %f",
(double)evt->edrx_cfg.edrx, (double)evt->edrx_cfg.ptw);
break;
CThe LTE link controller library is a layer above the nRF Modem library and provides functionality to control the LTE link on the nRF91 Series.
To enable the LTE link controller library in your application, enable the following Kconfig:
CONFIG_LTE_LINK_CONTROL=y
KconfigInclude the header file of the LTE link controller library in your source code.
#include <modem/lte_lc.h>
COne advantage to using the LTE link controller library is having a callback function that allows the application to get callbacks from the library, thereby offloading this process.
Define the callback function lte_handler()
.
For this lesson and subsequent exercise, LTE_LC_EVT_NW_REG_STATUS
is the only event where the callback function executes something. This event carries information about the modem’s network registration status, which can tell us if an LTE link has been established.
In the function below, we check the registration status of evt->nw_reg_status
of type lte_lc_nw_reg_status
and proceed to unblock the main()
function by giving the semaphore only if the registration status is of type registered home or registered roaming, indicating an LTE connection.
static void lte_handler(const struct lte_lc_evt *const evt)
{
switch (evt->type) {
case LTE_LC_EVT_NW_REG_STATUS:
if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
(evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
break;
}
LOG_INF("Network registration status: %s",
evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ?
"Connected - home network" : "Connected - roaming");
k_sem_give(<e_connected);
break;
default:
break;
}
}
CThe documentation for enum lte_lc_evt_type
explains all the event types in the LTE link controller library.
Initialize the library with lte_lc_init()
, which has the following signature.
lte_lc_init()
is deprecated in nRF Connect SDK v2.6.0 and higher.
Connect to the LTE network using the function lte_lc_connect_async()
, which has the following signature.
This function takes the callback function lte_handler()
that we defined in the previous step as a parameter.
We will use NCS_VERSION_NUMBER
to only call lte_lc_init()
if the nRF Connect SDK version is less than v2.6.0.
/* lte_lc_init deprecated in >= v2.6.0 */
#if NCS_VERSION_NUMBER < 0x20600
lte_lc_init();
#endif
lte_lc_connect_async(lte_handler);
CTo ensure the application doesn’t proceed with other operations until an LTE connection is established, we will add a semaphore.
Define the semaphore lte_connected
using K_SEM_DEFINE()
.
Since this semaphore will only be taken once, after the LTE connection function is called and given once, when the LTE connection is established, we pass initial_count
0 and count_limit
1.
K_SEM_DEFINE(lte_connected, 0, 1);
CAfter initiating the LTE connection, take the semaphore using k_sem_take()
.
k_sem_take(<e_connected, K_FOREVER);
CTo make sure the application doesn’t proceed until an LTE connection is established, we want to give the semaphore, using k_sem_give()
, in the event handler, after the registration status is confirmed as connected.
case LTE_LC_EVT_NW_REG_STATUS:
if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
(evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
break;
}
LOG_INF("Connected to: %s network\n",
evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ? "home" : "roaming");
k_sem_give(<e_connected);
break;
CEven though we are using a semaphore to make sure the application doesn’t proceed until an LTE connection is established, this is a non-blocking method because the application can still call functions and create threads after lte_lc_connect_async()
(or lte_lc_init_and_connect_async()
) has been called.
The LTE link controller library is a layer above the nRF Modem library and provides functionality to control the LTE link on the nRF91 Series.
1. To enable the LTE link controller library in your application, enable the following Kconfig:
CONFIG_LTE_LINK_CONTROL=y
Kconfig2. Disable the automatic init and connect functionality of the library
The library supports the functionality to automatically initialize and connect to the modem before the application starts. This functionality can reduce complexity, but it also increases the time until the application starts while blocking all other operations.
CONFIG_LTE_AUTO_INIT_AND_CONNECT=n
Kconfig3. Include the header file of the LTE link controller library in your source code.
#include <modem/lte_lc.h>
COne advantage to using the LTE link controller library is having a callback function that allows the application to get callbacks from the library, thereby offloading this process.
4. Define the callback function lte_handler()
.
For this lesson and subsequent exercise, LTE_LC_EVT_NW_REG_STATUS
is the only event where the callback function executes something. This event carries information about the modem’s network registration status, which can tell us if an LTE link has been established.
In the function below, we check the registration status of evt->nw_reg_status
of type lte_lc_nw_reg_status
and proceed to unblock the main()
function by giving the semaphore only if the registration status is of type registered home or registered roaming, indicating an LTE connection.
static void lte_handler(const struct lte_lc_evt *const evt)
{
switch (evt->type) {
case LTE_LC_EVT_NW_REG_STATUS:
if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
(evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
break;
}
LOG_INF("Network registration status: %s",
evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ?
"Connected - home network" : "Connected - roaming");
k_sem_give(<e_connected);
break;
default:
break;
}
}
CThe documentation for enum lte_lc_evt_type
explains all the event types in the LTE link controller library.
5.1 Initialize and connect to LET network using the function lte_lc_init_and_connect_async(lte_handler)
, which has the following signature
This function takes the callback function lte_handler()
that we defined in the previous step as a parameter.
lte_lc_init_and_connect_async(lte_handler);
CTo ensure the application doesn’t proceed with other operations until an LTE connection is established, we will add a semaphore.
6. Define the semaphore lte_connected
using K_SEM_DEFINE()
.
Since this semaphore will only be taken once, after the LTE connection function is called and given once, when the LTE connection is established, we pass initial_count
0 and count_limit
1.
K_SEM_DEFINE(lte_connected, 0, 1);
C7. After initiating the LTE connection, take the semaphore using k_sem_take()
.
k_sem_take(<e_connected, K_FOREVER);
C8. To make sure the application doesn’t proceed until an LTE connection is established, we want to give the semaphore, using k_sem_give()
, in the event handler, after the registration status is confirmed as connected.
case LTE_LC_EVT_NW_REG_STATUS:
if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
(evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
break;
}
LOG_INF("Connected to: %s network\n",
evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ? "home" : "roaming");
k_sem_give(<e_connected);
break;
CEven though we are using a semaphore to make sure the application doesn’t proceed until an LTE connection is established, this is a non-blocking method because the application can still call functions and create threads after lte_lc_connect_async()
(or lte_lc_init_and_connect_async()
) has been called.