Skip to content

Commit 5ce1486

Browse files
tokangasnordicjm
authored andcommitted
lib: lte_link_control: Rework modem events
Because of new modem events which have values, there was need to rework how modem events are delivered in struct lte_lc_evt. The enum lte_lc_modem_evt has been replaced by a struct lte_lc_modem_evt which contains the modem event type and possible associated payload. This requires a minor code change to all applications using modem events. Modem events LTE_LC_MODEM_EVT_CE_LEVEL_0, LTE_LC_MODEM_EVT_CE_LEVEL_1, LTE_LC_MODEM_EVT_CE_LEVEL_2 and LTE_LC_MODEM_EVT_CE_LEVEL_3 have been replaced by event LTE_LC_MODEM_EVT_CE_LEVEL, which has associated payload for the value. Added support for new modem events: LTE_LC_MODEM_EVT_RF_CAL_NOT_DONE LTE_LC_MODEM_EVT_INVALID_BAND_CONF LTE_LC_MODEM_EVT_DETECTED_COUNTRY Signed-off-by: Tommi Kangas <[email protected]>
1 parent bf0afe8 commit 5ce1486

File tree

10 files changed

+262
-97
lines changed

10 files changed

+262
-97
lines changed

doc/nrf/releases_and_maturity/migration/migration_guide_3.2.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,16 @@ Libraries
8484

8585
This section describes the changes related to libraries.
8686

87-
|no_changes_yet_note|
87+
.. toggle::
88+
89+
* :ref:`lte_lc_readme` library:
90+
91+
* The type of the :c:member:`lte_lc_evt.modem_evt` field has been changed to :c:struct:`lte_lc_modem_evt`.
92+
The modem event type can be determined from the :c:member:`lte_lc_modem_evt.type` field.
93+
Applications using modem events need to be updated to read the event type from ``modem_evt.type`` instead of ``modem_evt``.
94+
95+
* Modem events ``LTE_LC_MODEM_EVT_CE_LEVEL_0``, ``LTE_LC_MODEM_EVT_CE_LEVEL_1``, ``LTE_LC_MODEM_EVT_CE_LEVEL_2`` and ``LTE_LC_MODEM_EVT_CE_LEVEL_3`` have been replaced by event :c:enumerator:`LTE_LC_MODEM_EVT_CE_LEVEL`.
96+
The CE level can be read from :c:member:`lte_lc_modem_evt.ce_level`.
8897

8998
Trusted Firmware-M
9099
==================

doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,12 @@ Modem libraries
633633
* Support for environment evaluation.
634634
* Support for NTN NB-IoT system mode.
635635
* eDRX support for NTN NB-IoT.
636+
* Support for new modem events :c:enumerator:`LTE_LC_MODEM_EVT_RF_CAL_NOT_DONE`, :c:enumerator:`LTE_LC_MODEM_EVT_INVALID_BAND_CONF`, and :c:enumerator:`LTE_LC_MODEM_EVT_DETECTED_COUNTRY`.
637+
638+
* Updated:
639+
640+
* The type of the :c:member:`lte_lc_evt.modem_evt` field to :c:struct:`lte_lc_modem_evt`.
641+
* Replaced modem events ``LTE_LC_MODEM_EVT_CE_LEVEL_0``, ``LTE_LC_MODEM_EVT_CE_LEVEL_1``, ``LTE_LC_MODEM_EVT_CE_LEVEL_2`` and ``LTE_LC_MODEM_EVT_CE_LEVEL_3`` with the :c:enumerator:`LTE_LC_MODEM_EVT_CE_LEVEL` modem event.
636642

637643
Multiprotocol Service Layer libraries
638644
-------------------------------------

include/modem/lte_lc.h

Lines changed: 74 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ enum lte_lc_modem_sleep_type {
610610
* Proprietary PSM.
611611
*
612612
* @note This is only supported by the following modem firmware:
613-
* - mfw_nrf91x1 >= v2.0.0
613+
* - mfw_nrf91x1
614614
* - mfw_nrf9151-ntn
615615
*/
616616
LTE_LC_MODEM_SLEEP_PROPRIETARY_PSM = 7,
@@ -705,8 +705,8 @@ enum lte_lc_ce_level {
705705
LTE_LC_CE_LEVEL_UNKNOWN = UINT8_MAX,
706706
};
707707

708-
/** Modem domain events. */
709-
enum lte_lc_modem_evt {
708+
/** Modem domain event type. */
709+
enum lte_lc_modem_evt_type {
710710
/**
711711
* Indicates that a light search has been performed.
712712
*
@@ -751,40 +751,97 @@ enum lte_lc_modem_evt {
751751
LTE_LC_MODEM_EVT_NO_IMEI,
752752

753753
/**
754-
* Selected CE level in RACH procedure is 0, see 3GPP TS 36.331 for details.
754+
* Selected CE level in RACH procedure. See 3GPP TS 36.331 for details.
755+
*
756+
* The associated payload is the @c lte_lc_modem_evt.ce_level member of type
757+
* @ref lte_lc_ce_level in the event.
755758
*
756759
* @note This is only supported by the following modem firmware:
757-
* - mfw_nrf91x1 >= v2.0.0
760+
* - mfw_nrf91x1
758761
* - mfw_nrf9151-ntn
759762
*/
760-
LTE_LC_MODEM_EVT_CE_LEVEL_0,
763+
LTE_LC_MODEM_EVT_CE_LEVEL,
761764

762765
/**
763-
* Selected CE level in RACH procedure is 1, see 3GPP TS 36.331 for details.
766+
* RF calibration or power class selection not done.
764767
*
765768
* @note This is only supported by the following modem firmware:
766-
* - mfw_nrf91x1 >= v2.0.0
769+
* - mfw_nrf91x1
767770
* - mfw_nrf9151-ntn
768771
*/
769-
LTE_LC_MODEM_EVT_CE_LEVEL_1,
772+
LTE_LC_MODEM_EVT_RF_CAL_NOT_DONE,
770773

771774
/**
772-
* Selected CE level in RACH procedure is 2, see 3GPP TS 36.331 for details.
775+
* Invalid band configuration.
776+
*
777+
* The associated payload is the @c lte_lc_modem_evt.invalid_band_conf member of type
778+
* @ref lte_lc_invalid_band_conf in the event.
773779
*
774780
* @note This is only supported by the following modem firmware:
775-
* - mfw_nrf91x1 >= v2.0.0
781+
* - mfw_nrf91x1
776782
* - mfw_nrf9151-ntn
777783
*/
778-
LTE_LC_MODEM_EVT_CE_LEVEL_2,
784+
LTE_LC_MODEM_EVT_INVALID_BAND_CONF,
779785

780786
/**
781-
* Selected CE level in RACH procedure is 3, see 3GPP TS 36.331 for details.
787+
* Current country the device is operating in.
788+
*
789+
* The associated payload is the @c lte_lc_modem_evt.detected_country member of type
790+
* `uint32_t` in the event. The country is reported as a Mobile Country Code (MCC).
782791
*
783792
* @note This is only supported by the following modem firmware:
784-
* - mfw_nrf91x1 >= v2.0.0
785793
* - mfw_nrf9151-ntn
786794
*/
787-
LTE_LC_MODEM_EVT_CE_LEVEL_3,
795+
LTE_LC_MODEM_EVT_DETECTED_COUNTRY
796+
};
797+
798+
/** Band configuration status. */
799+
enum lte_lc_band_conf_status {
800+
/** Usable bands available in system. */
801+
LTE_LC_BAND_CONF_STATUS_OK = 0,
802+
803+
/** No usable bands available in system. */
804+
LTE_LC_BAND_CONF_STATUS_INVALID = 1,
805+
806+
/** System support not configured. */
807+
LTE_LC_BAND_CONF_STATUS_SYSTEM_NOT_SUPPORTED = 2
808+
};
809+
810+
/** Detected conflicting band lock or operator restrictions. */
811+
struct lte_lc_invalid_band_conf {
812+
/** LTE-M band configuration status. */
813+
enum lte_lc_band_conf_status status_ltem;
814+
815+
/** NB-IoT band configuration status. */
816+
enum lte_lc_band_conf_status status_nbiot;
817+
818+
/** NTN NB-IoT band configuration status. */
819+
enum lte_lc_band_conf_status status_ntn_nbiot;
820+
};
821+
822+
/** Modem domain event.
823+
*
824+
* This structure is used as the payload for event @ref LTE_LC_EVT_MODEM_EVENT.
825+
*/
826+
struct lte_lc_modem_evt {
827+
/** Event type. */
828+
enum lte_lc_modem_evt_type type;
829+
830+
/** Payload for the event (optional). */
831+
union {
832+
/** Payload for event @ref LTE_LC_MODEM_EVT_CE_LEVEL. */
833+
enum lte_lc_ce_level ce_level;
834+
835+
/** Payload for event @ref LTE_LC_MODEM_EVT_INVALID_BAND_CONF. */
836+
struct lte_lc_invalid_band_conf invalid_band_conf;
837+
838+
/**
839+
* Payload for event @ref LTE_LC_MODEM_EVT_DETECTED_COUNTRY.
840+
*
841+
* Mobile Country Code (MCC) for the detected country.
842+
*/
843+
uint32_t detected_country;
844+
};
788845
};
789846

790847
/** RAI configuration. */
@@ -1346,7 +1403,7 @@ struct lte_lc_evt {
13461403
#endif /* CONFIG_LTE_LC_MODEM_SLEEP_MODULE */
13471404

13481405
/** Payload for event @ref LTE_LC_EVT_MODEM_EVENT. */
1349-
enum lte_lc_modem_evt modem_evt;
1406+
struct lte_lc_modem_evt modem_evt;
13501407

13511408
/**
13521409
* Payload for event @ref LTE_LC_EVT_TAU_PRE_WARNING.
@@ -1620,7 +1677,7 @@ int lte_lc_psm_get(int *tau, int *active_time);
16201677
* `CONFIG_LTE_PROPRIETARY_PSM_REQ` if it is called during modem initialization.
16211678
*
16221679
* @note This is only supported by the following modem firmware:
1623-
* - mfw_nrf91x1 >= v2.0.0
1680+
* - mfw_nrf91x1
16241681
* - mfw_nrf9151-ntn
16251682
*
16261683
* @note Requires `CONFIG_LTE_LC_PSM_MODULE` to be enabled.

lib/lte_link_control/modules/mdmev.c

Lines changed: 92 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -19,77 +19,126 @@
1919

2020
LOG_MODULE_DECLARE(lte_lc, CONFIG_LTE_LINK_CONTROL_LOG_LEVEL);
2121

22-
/* MDMEV command parameters */
23-
#define AT_MDMEV_ENABLE_1 "AT%%MDMEV=1"
24-
#define AT_MDMEV_ENABLE_2 "AT%%MDMEV=2"
25-
#define AT_MDMEV_DISABLE "AT%%MDMEV=0"
26-
#define AT_MDMEV_RESPONSE_PREFIX "%MDMEV: "
27-
#define AT_MDMEV_OVERHEATED "ME OVERHEATED\r\n"
28-
#define AT_MDMEV_BATTERY_LOW "ME BATTERY LOW\r\n"
29-
#define AT_MDMEV_SEARCH_STATUS_1 "SEARCH STATUS 1\r\n"
30-
#define AT_MDMEV_SEARCH_STATUS_2 "SEARCH STATUS 2\r\n"
31-
#define AT_MDMEV_RESET_LOOP "RESET LOOP\r\n"
32-
#define AT_MDMEV_NO_IMEI "NO IMEI\r\n"
33-
#define AT_MDMEV_CE_LEVEL_0 "PRACH CE-LEVEL 0\r\n"
34-
#define AT_MDMEV_CE_LEVEL_1 "PRACH CE-LEVEL 1\r\n"
35-
#define AT_MDMEV_CE_LEVEL_2 "PRACH CE-LEVEL 2\r\n"
36-
#define AT_MDMEV_CE_LEVEL_3 "PRACH CE-LEVEL 3\r\n"
22+
/* %MDMEV commands */
23+
#define AT_MDMEV_ENABLE_1 "AT%%MDMEV=1"
24+
#define AT_MDMEV_ENABLE_2 "AT%%MDMEV=2"
25+
#define AT_MDMEV_DISABLE "AT%%MDMEV=0"
26+
#define AT_MDMEV_NOTIF_PREFIX "%MDMEV: "
27+
28+
/* Fixed events */
29+
#define AT_MDMEV_OVERHEATED "ME OVERHEATED\r\n"
30+
#define AT_MDMEV_BATTERY_LOW "ME BATTERY LOW\r\n"
31+
#define AT_MDMEV_SEARCH_STATUS_1 "SEARCH STATUS 1\r\n"
32+
#define AT_MDMEV_SEARCH_STATUS_2 "SEARCH STATUS 2\r\n"
33+
#define AT_MDMEV_RESET_LOOP "RESET LOOP\r\n"
34+
#define AT_MDMEV_NO_IMEI "NO IMEI\r\n"
35+
#define AT_MDMEV_RF_CAL_NOT_DONE "RF CALIBRATION NOT DONE\r\n"
36+
37+
/* Events with values */
38+
#define AT_MDMEV_CE_LEVEL "PRACH CE-LEVEL %u\r\n"
39+
#define AT_MDMEV_INVALID_BAND_CONF "INVALID BAND CONFIGURATION %u %u %u\r\n"
40+
#define AT_MDMEV_DETECTED_COUNTRY "DETECTED COUNTRY %u\r\n"
3741

3842
AT_MONITOR(ltelc_atmon_mdmev, "%MDMEV", at_handler_mdmev);
3943

4044
bool mdmev_enabled;
4145

42-
static int mdmev_parse(const char *at_response, enum lte_lc_modem_evt *modem_evt)
46+
static int mdmev_fixed_parse(const char *notif, struct lte_lc_modem_evt *modem_evt)
4347
{
44-
static const char *const event_types[] = {
45-
[LTE_LC_MODEM_EVT_LIGHT_SEARCH_DONE] = AT_MDMEV_SEARCH_STATUS_1,
46-
[LTE_LC_MODEM_EVT_SEARCH_DONE] = AT_MDMEV_SEARCH_STATUS_2,
47-
[LTE_LC_MODEM_EVT_RESET_LOOP] = AT_MDMEV_RESET_LOOP,
48-
[LTE_LC_MODEM_EVT_BATTERY_LOW] = AT_MDMEV_BATTERY_LOW,
49-
[LTE_LC_MODEM_EVT_OVERHEATED] = AT_MDMEV_OVERHEATED,
50-
[LTE_LC_MODEM_EVT_NO_IMEI] = AT_MDMEV_NO_IMEI,
51-
[LTE_LC_MODEM_EVT_CE_LEVEL_0] = AT_MDMEV_CE_LEVEL_0,
52-
[LTE_LC_MODEM_EVT_CE_LEVEL_1] = AT_MDMEV_CE_LEVEL_1,
53-
[LTE_LC_MODEM_EVT_CE_LEVEL_2] = AT_MDMEV_CE_LEVEL_2,
54-
[LTE_LC_MODEM_EVT_CE_LEVEL_3] = AT_MDMEV_CE_LEVEL_3,
48+
struct event_type_map {
49+
enum lte_lc_modem_evt_type type;
50+
const char *notif;
51+
};
52+
static const struct event_type_map event_types[] = {
53+
{ LTE_LC_MODEM_EVT_LIGHT_SEARCH_DONE, AT_MDMEV_SEARCH_STATUS_1 },
54+
{ LTE_LC_MODEM_EVT_SEARCH_DONE, AT_MDMEV_SEARCH_STATUS_2 },
55+
{ LTE_LC_MODEM_EVT_RESET_LOOP, AT_MDMEV_RESET_LOOP },
56+
{ LTE_LC_MODEM_EVT_BATTERY_LOW, AT_MDMEV_BATTERY_LOW },
57+
{ LTE_LC_MODEM_EVT_OVERHEATED, AT_MDMEV_OVERHEATED },
58+
{ LTE_LC_MODEM_EVT_NO_IMEI, AT_MDMEV_NO_IMEI },
59+
{ LTE_LC_MODEM_EVT_RF_CAL_NOT_DONE, AT_MDMEV_RF_CAL_NOT_DONE },
60+
{ 0, NULL }
5561
};
5662

57-
__ASSERT_NO_MSG(at_response != NULL);
63+
__ASSERT_NO_MSG(notif != NULL);
5864
__ASSERT_NO_MSG(modem_evt != NULL);
5965

60-
const char *start_ptr = at_response + sizeof(AT_MDMEV_RESPONSE_PREFIX) - 1;
61-
6266
for (size_t i = 0; i < ARRAY_SIZE(event_types); i++) {
63-
if (strcmp(event_types[i], start_ptr) == 0) {
64-
LOG_DBG("Occurrence found: %s", event_types[i]);
65-
*modem_evt = i;
67+
if (event_types[i].notif == NULL) {
68+
break;
69+
}
70+
71+
if (strcmp(event_types[i].notif, notif) == 0) {
72+
modem_evt->type = event_types[i].type;
6673

6774
return 0;
6875
}
6976
}
7077

71-
LOG_DBG("No modem event type found: %s", at_response);
78+
return -ENODATA;
79+
}
80+
81+
static int mdmev_value_parse(const char *notif, struct lte_lc_modem_evt *modem_evt)
82+
{
83+
uint32_t value1;
84+
uint32_t value2;
85+
uint32_t value3;
86+
87+
__ASSERT_NO_MSG(notif != NULL);
88+
__ASSERT_NO_MSG(modem_evt != NULL);
89+
90+
if (sscanf(notif, AT_MDMEV_CE_LEVEL, &value1) == 1) {
91+
modem_evt->type = LTE_LC_MODEM_EVT_CE_LEVEL;
92+
modem_evt->ce_level = value1;
93+
return 0;
94+
}
95+
96+
/* Default value for NTN NB-IoT when it's not supported by the modem firmware. */
97+
value3 = LTE_LC_BAND_CONF_STATUS_SYSTEM_NOT_SUPPORTED;
98+
99+
/* At least 2 values are expected (LTE-M and NB-IoT). */
100+
if (sscanf(notif, AT_MDMEV_INVALID_BAND_CONF, &value1, &value2, &value3) >= 2) {
101+
modem_evt->type = LTE_LC_MODEM_EVT_INVALID_BAND_CONF;
102+
modem_evt->invalid_band_conf.status_ltem = value1;
103+
modem_evt->invalid_band_conf.status_nbiot = value2;
104+
modem_evt->invalid_band_conf.status_ntn_nbiot = value3;
105+
return 0;
106+
}
107+
108+
if (sscanf(notif, AT_MDMEV_DETECTED_COUNTRY, &value1) == 1) {
109+
modem_evt->type = LTE_LC_MODEM_EVT_DETECTED_COUNTRY;
110+
modem_evt->detected_country = value1;
111+
return 0;
112+
}
72113

73114
return -ENODATA;
74115
}
75116

76-
static void at_handler_mdmev(const char *response)
117+
static void at_handler_mdmev(const char *notif)
77118
{
78119
int err;
79-
struct lte_lc_evt evt = {0};
120+
struct lte_lc_evt evt = {
121+
.type = LTE_LC_EVT_MODEM_EVENT
122+
};
123+
124+
__ASSERT_NO_MSG(notif != NULL);
80125

81-
__ASSERT_NO_MSG(response != NULL);
126+
/* Remove the notification prefix. */
127+
const char *start_ptr = notif + sizeof(AT_MDMEV_NOTIF_PREFIX) - 1;
82128

83-
LOG_DBG("%%MDMEV notification");
129+
LOG_DBG("%%MDMEV notification: %.*s", (int)(strlen(start_ptr) - strlen("\r\n")), start_ptr);
84130

85-
err = mdmev_parse(response, &evt.modem_evt);
131+
/* Try to parse fixed events. */
132+
err = mdmev_fixed_parse(start_ptr, &evt.modem_evt);
86133
if (err) {
87-
LOG_ERR("Can't parse modem event notification, error: %d", err);
88-
return;
134+
/* Try to parse events with values. */
135+
err = mdmev_value_parse(start_ptr, &evt.modem_evt);
136+
if (err) {
137+
LOG_DBG("No modem event type found: %s", notif);
138+
return;
139+
}
89140
}
90141

91-
evt.type = LTE_LC_EVT_MODEM_EVENT;
92-
93142
event_handler_list_dispatch(&evt);
94143
}
95144

lib/nrf_modem_lib/lte_net_if/lte_net_if.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,8 @@ static void pdn_event_handler(uint8_t cid, enum pdn_event event, int reason)
334334

335335
static void lte_reg_handler(const struct lte_lc_evt *const evt)
336336
{
337-
if (evt->type == LTE_LC_EVT_MODEM_EVENT && evt->modem_evt == LTE_LC_MODEM_EVT_RESET_LOOP) {
337+
if (evt->type == LTE_LC_EVT_MODEM_EVENT &&
338+
evt->modem_evt.type == LTE_LC_MODEM_EVT_RESET_LOOP) {
338339
LOG_WRN("The modem has detected a reset loop. LTE network attach is now "
339340
"restricted for the next 30 minutes.");
340341

modules/memfault-firmware-sdk/memfault_lte_metrics.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ static void lte_handler(const struct lte_lc_evt *const evt)
193193

194194
break;
195195
case LTE_LC_EVT_MODEM_EVENT:
196-
if (evt->modem_evt == LTE_LC_MODEM_EVT_RESET_LOOP) {
196+
if (evt->modem_evt.type == LTE_LC_MODEM_EVT_RESET_LOOP) {
197197
MEMFAULT_METRIC_ADD(ncs_lte_reset_loop_detected_count, 1);
198198
}
199199
break;

0 commit comments

Comments
 (0)