|
19 | 19 |
|
20 | 20 | LOG_MODULE_DECLARE(lte_lc, CONFIG_LTE_LINK_CONTROL_LOG_LEVEL);
|
21 | 21 |
|
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" |
37 | 41 |
|
38 | 42 | AT_MONITOR(ltelc_atmon_mdmev, "%MDMEV", at_handler_mdmev);
|
39 | 43 |
|
40 | 44 | bool mdmev_enabled;
|
41 | 45 |
|
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) |
43 | 47 | {
|
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 } |
55 | 61 | };
|
56 | 62 |
|
57 |
| - __ASSERT_NO_MSG(at_response != NULL); |
| 63 | + __ASSERT_NO_MSG(notif != NULL); |
58 | 64 | __ASSERT_NO_MSG(modem_evt != NULL);
|
59 | 65 |
|
60 |
| - const char *start_ptr = at_response + sizeof(AT_MDMEV_RESPONSE_PREFIX) - 1; |
61 |
| - |
62 | 66 | 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; |
66 | 73 |
|
67 | 74 | return 0;
|
68 | 75 | }
|
69 | 76 | }
|
70 | 77 |
|
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 | + } |
72 | 113 |
|
73 | 114 | return -ENODATA;
|
74 | 115 | }
|
75 | 116 |
|
76 |
| -static void at_handler_mdmev(const char *response) |
| 117 | +static void at_handler_mdmev(const char *notif) |
77 | 118 | {
|
78 | 119 | 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); |
80 | 125 |
|
81 |
| - __ASSERT_NO_MSG(response != NULL); |
| 126 | + /* Remove the notification prefix. */ |
| 127 | + const char *start_ptr = notif + sizeof(AT_MDMEV_NOTIF_PREFIX) - 1; |
82 | 128 |
|
83 |
| - LOG_DBG("%%MDMEV notification"); |
| 129 | + LOG_DBG("%%MDMEV notification: %.*s", (int)(strlen(start_ptr) - strlen("\r\n")), start_ptr); |
84 | 130 |
|
85 |
| - err = mdmev_parse(response, &evt.modem_evt); |
| 131 | + /* Try to parse fixed events. */ |
| 132 | + err = mdmev_fixed_parse(start_ptr, &evt.modem_evt); |
86 | 133 | 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 | + } |
89 | 140 | }
|
90 | 141 |
|
91 |
| - evt.type = LTE_LC_EVT_MODEM_EVENT; |
92 |
| - |
93 | 142 | event_handler_list_dispatch(&evt);
|
94 | 143 | }
|
95 | 144 |
|
|
0 commit comments