nRF Connect SDK API 0.1.0
Loading...
Searching...
No Matches
lte_lc_helpers.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5 */
6
7#include <zephyr/kernel.h>
8#include <zephyr/types.h>
9#include <string.h>
10#include <stdio.h>
11#include <modem/lte_lc.h>
12#include <zephyr/logging/log.h>
13
14#define AT_CFUN_READ "AT+CFUN?"
15#define AT_CEREG_5 "AT+CEREG=5"
16#define AT_CEREG_READ "AT+CEREG?"
17#define AT_CEREG_REG_STATUS_INDEX 1
18#define AT_CEREG_TAC_INDEX 2
19#define AT_CEREG_CELL_ID_INDEX 3
20#define AT_CEREG_ACT_INDEX 4
21#define AT_CEREG_CAUSE_TYPE_INDEX 5
22#define AT_CEREG_REJECT_CAUSE_INDEX 6
23#define AT_CEREG_ACTIVE_TIME_INDEX 7
24#define AT_CEREG_TAU_INDEX 8
25#define AT_XSYSTEMMODE_READ "AT%XSYSTEMMODE?"
26
27/* The indices are for the set command. Add 1 for the read command indices. */
28#define AT_XSYSTEMMODE_READ_LTEM_INDEX 1
29#define AT_XSYSTEMMODE_READ_NBIOT_INDEX 2
30#define AT_XSYSTEMMODE_READ_GPS_INDEX 3
31#define AT_XSYSTEMMODE_READ_PREFERENCE_INDEX 4
32
33/* CEDRXS command parameters */
34#define AT_CEDRXS_MODE_INDEX
35#define AT_CEDRXS_ACTT_WB 4
36#define AT_CEDRXS_ACTT_NB 5
37
38/* CEDRXP notification parameters */
39#define AT_CEDRXP_ACTT_INDEX 1
40#define AT_CEDRXP_REQ_EDRX_INDEX 2
41#define AT_CEDRXP_NW_EDRX_INDEX 3
42#define AT_CEDRXP_NW_PTW_INDEX 4
43
44/* CSCON command parameters */
45#define AT_CSCON_RRC_MODE_INDEX 1
46#define AT_CSCON_READ_RRC_MODE_INDEX 2
47
48/* XT3412 command parameters */
49#define AT_XT3412_SUB "AT%%XT3412=1,%d,%d"
50#define AT_XT3412_TIME_INDEX 1
51#define T3412_MAX 35712000000
52
53/* NCELLMEAS notification parameters */
54#define AT_NCELLMEAS_START "AT%%NCELLMEAS"
55#define AT_NCELLMEAS_STOP "AT%%NCELLMEASSTOP"
56#define AT_NCELLMEAS_STATUS_INDEX 1
57#define AT_NCELLMEAS_STATUS_VALUE_SUCCESS 0
58#define AT_NCELLMEAS_STATUS_VALUE_FAIL 1
59#define AT_NCELLMEAS_STATUS_VALUE_INCOMPLETE 2
60#define AT_NCELLMEAS_CELL_ID_INDEX 2
61#define AT_NCELLMEAS_PLMN_INDEX 3
62#define AT_NCELLMEAS_TAC_INDEX 4
63#define AT_NCELLMEAS_TIMING_ADV_INDEX 5
64#define AT_NCELLMEAS_EARFCN_INDEX 6
65#define AT_NCELLMEAS_PHYS_CELL_ID_INDEX 7
66#define AT_NCELLMEAS_RSRP_INDEX 8
67#define AT_NCELLMEAS_RSRQ_INDEX 9
68#define AT_NCELLMEAS_MEASUREMENT_TIME_INDEX 10
69#define AT_NCELLMEAS_PRE_NCELLS_PARAMS_COUNT 11
70/* The rest of the parameters are in repeating arrays per neighboring cell.
71 * The indices below refer to their index within such a repeating array.
72 */
73#define AT_NCELLMEAS_N_EARFCN_INDEX 0
74#define AT_NCELLMEAS_N_PHYS_CELL_ID_INDEX 1
75#define AT_NCELLMEAS_N_RSRP_INDEX 2
76#define AT_NCELLMEAS_N_RSRQ_INDEX 3
77#define AT_NCELLMEAS_N_TIME_DIFF_INDEX 4
78#define AT_NCELLMEAS_N_PARAMS_COUNT 5
79#define AT_NCELLMEAS_N_MAX_ARRAY_SIZE CONFIG_LTE_NEIGHBOR_CELLS_MAX
80
81#define AT_NCELLMEAS_PARAMS_COUNT_MAX \
82 (AT_NCELLMEAS_PRE_NCELLS_PARAMS_COUNT + \
83 AT_NCELLMEAS_N_PARAMS_COUNT * CONFIG_LTE_NEIGHBOR_CELLS_MAX)
84
85#define AT_NCELLMEAS_GCI_CELL_PARAMS_COUNT 12
86
87/* XMODEMSLEEP command parameters. */
88#define AT_XMODEMSLEEP_SUB "AT%%XMODEMSLEEP=1,%d,%d"
89#define AT_XMODEMSLEEP_PARAMS_COUNT_MAX 4
90#define AT_XMODEMSLEEP_TYPE_INDEX 1
91#define AT_XMODEMSLEEP_TIME_INDEX 2
92
93/* CONEVAL command parameters */
94#define AT_CONEVAL_READ "AT%CONEVAL"
95#define AT_CONEVAL_PARAMS_MAX 19
96#define AT_CONEVAL_RESULT_INDEX 1
97#define AT_CONEVAL_RRC_STATE_INDEX 2
98#define AT_CONEVAL_ENERGY_ESTIMATE_INDEX 3
99#define AT_CONEVAL_RSRP_INDEX 4
100#define AT_CONEVAL_RSRQ_INDEX 5
101#define AT_CONEVAL_SNR_INDEX 6
102#define AT_CONEVAL_CELL_ID_INDEX 7
103#define AT_CONEVAL_PLMN_INDEX 8
104#define AT_CONEVAL_PHYSICAL_CELL_ID_INDEX 9
105#define AT_CONEVAL_EARFCN_INDEX 10
106#define AT_CONEVAL_BAND_INDEX 11
107#define AT_CONEVAL_TAU_TRIGGERED_INDEX 12
108#define AT_CONEVAL_CE_LEVEL_INDEX 13
109#define AT_CONEVAL_TX_POWER_INDEX 14
110#define AT_CONEVAL_TX_REPETITIONS_INDEX 15
111#define AT_CONEVAL_RX_REPETITIONS_INDEX 16
112#define AT_CONEVAL_DL_PATHLOSS_INDEX 17
113
114/* MDMEV command parameters */
115#define AT_MDMEV_ENABLE_1 "AT%%MDMEV=1"
116#define AT_MDMEV_ENABLE_2 "AT%%MDMEV=2"
117#define AT_MDMEV_DISABLE "AT%%MDMEV=0"
118#define AT_MDMEV_RESPONSE_PREFIX "%MDMEV: "
119#define AT_MDMEV_OVERHEATED "ME OVERHEATED\r\n"
120#define AT_MDMEV_BATTERY_LOW "ME BATTERY LOW\r\n"
121#define AT_MDMEV_SEARCH_STATUS_1 "SEARCH STATUS 1\r\n"
122#define AT_MDMEV_SEARCH_STATUS_2 "SEARCH STATUS 2\r\n"
123#define AT_MDMEV_RESET_LOOP "RESET LOOP\r\n"
124#define AT_MDMEV_NO_IMEI "NO IMEI\r\n"
125#define AT_MDMEV_CE_LEVEL_0 "PRACH CE-LEVEL 0\r\n"
126#define AT_MDMEV_CE_LEVEL_1 "PRACH CE-LEVEL 1\r\n"
127#define AT_MDMEV_CE_LEVEL_2 "PRACH CE-LEVEL 2\r\n"
128#define AT_MDMEV_CE_LEVEL_3 "PRACH CE-LEVEL 3\r\n"
129
130/* RAI notification parameters */
131#define AT_RAI_RESPONSE_PREFIX "%RAI"
132#define AT_RAI_PARAMS_COUNT_MAX 5
133#define AT_RAI_CELL_ID_INDEX 1
134#define AT_RAI_PLMN_INDEX 2
135#define AT_RAI_AS_INDEX 3
136#define AT_RAI_CP_INDEX 4
137
138/* @brief Parses an AT command response, and returns the current RRC mode.
139 *
140 * @param at_response Pointer to buffer with AT response.
141 * @param mode Pointer to where the RRC mode is stored.
142 * @param mode_index Parameter index for mode.
143 *
144 * @return Zero on success or (negative) error code otherwise.
145 */
146int parse_rrc_mode(const char *at_response,
147 enum lte_lc_rrc_mode *mode,
148 size_t mode_index);
149
150/* @brief Parses an AT command response and returns the current eDRX configuration.
151 *
152 * @note It is assumed that the network only reports valid eDRX values when
153 * in each mode (LTE-M and NB1). There is no sanity check of these values.
154 *
155 * @param[in] at_response Pointer to buffer with AT response.
156 * @param[in] cfg Pointer to where the eDRX configuration is stored.
157 * @param[out] edrx_str eDRX value as a string. Must be 5 characters long buffer.
158 * @param[out] ptw_str PTW as a string. Must be 5 characters long buffer.
159 *
160 * @return Zero on success or (negative) error code otherwise.
161 */
162int parse_edrx(const char *at_response, struct lte_lc_edrx_cfg *cfg, char *edrx_str, char *ptw_str);
163
164/* @brief Parses PSM configuration from periodic TAU timer and active time strings.
165 *
166 * @param active_time_str Pointer to active time string.
167 * @param tau_ext_str Pointer to TAU (T3412 extended) string.
168 * @param tau_legacy_str Pointer to TAU (T3412) string.
169 * @param psm_cfg Pointer to PSM configuraion struct where the parsed values
170 * are stored.
171 *
172 * @retval 0 if PSM configuration was successfully parsed.
173 * @retval -EINVAL if parsing failed.
174 */
175int parse_psm(const char *active_time_str, const char *tau_ext_str,
176 const char *tau_legacy_str, struct lte_lc_psm_cfg *psm_cfg);
177
178/* @brief Encode Periodic TAU timer and active time strings.
179 *
180 * @param[out] tau_ext_str TAU (T3412 extended) string. Must be at least 9 bytes.
181 * @param[out] active_time_str Active time string buffer. Must be at least 9 bytes.
182 * @param rptau[in] Requested Periodic TAU value to be encoded.
183 * @param rat[in] Requested active time value to be encoded.
184 *
185 * @retval 0 if PSM configuration was successfully parsed.
186 * @retval -EINVAL if parsing failed.
187 */
188int encode_psm(char *tau_ext_str, char *active_time_str, int rptau, int rat);
189
190/* @brief Parses a +CEREG notification and returns network registration status,
191 * cell information, LTE mode and PSM configuration. The function always
192 * initializes the return values. The destination pointers must be non-NULL.
193 *
194 * @param[in] at_response AT notification.
195 * @param[out] reg_status Registration status.
196 * @param[out] cell Cell information.
197 * @param[out] lte_mode LTE mode.
198 * @param[out] psm_cfg PSM configuration.
199 *
200 * @return Zero on success or (negative) error code otherwise.
201 */
202int parse_cereg(const char *at_response,
203 enum lte_lc_nw_reg_status *reg_status,
204 struct lte_lc_cell *cell,
205 enum lte_lc_lte_mode *lte_mode,
206 struct lte_lc_psm_cfg *psm_cfg);
207
208/* @brief Parses an XT3412 response and extracts the time until next TAU.
209 *
210 * @param at_response Pointer to buffer with AT response.
211 * @param time Pointer to integer that the time until next TAU will be written to.
212 *
213 * @return Zero on success or (negative) error code otherwise.
214 */
215int parse_xt3412(const char *at_response, uint64_t *time);
216
217/* @brief Get the number of neighboring cells reported in an NCELLMEAS response.
218 *
219 * @param at_response Pointer to buffer with AT response to parse.
220 *
221 * @return The number of neighbor cells found in the response.
222 */
223uint32_t neighborcell_count_get(const char *at_response);
224
225/* @brief Parses an NCELLMEAS notification and stores neighboring cell
226 * information in a struct.
227 *
228 * 18446744073709551614 is the maximum value for timing_advance_meas_time and
229 * measurement_time in @ref lte_lc_cells_info.
230 * This value could be represented with uint64_t but cannot be stored by at_parser,
231 * which internally uses int64_t value for all integers.
232 * Hence, the maximum value for these fields is represented by 63 bits and is
233 * 9223372036854775807, which still represents millions of years.
234 *
235 * @param at_response AT response.
236 * @param cells Neighbor cell structure.
237 * The current cell information is valid if the current cell ID is
238 * not set to LTE_LC_CELL_EUTRAN_ID_INVALID.
239 *
240 * @return Zero on success or (negative) error code otherwise.
241 * @retval 1 Measurement failure.
242 * @retval -E2BIG The static buffers set by CONFIG_LTE_NEIGHBOR_CELLS_MAX
243 * are too small for the modem response. The associated data is still valid,
244 * but not complete.
245 */
246int parse_ncellmeas(const char *at_response, struct lte_lc_cells_info *cells);
247
248/* @brief Parses a NCELLMEAS notification for GCI search types, and stores neighboring cell
249 * and measured GCI cell information in a struct.
250 *
251 * 18446744073709551614 is the maximum value for timing_advance_meas_time and
252 * measurement_time in @ref lte_lc_cells_info.
253 * This value could be represented with uint64_t but cannot be stored by at_parser,
254 * which internally uses int64_t value for all integers.
255 * Hence, the maximum value for these fields is represented by 63 bits and is
256 * 9223372036854775807, which still represents millions of years.
257 *
258 * @param params Neighbor cell measurement parameters.
259 * @param at_response AT response.
260 * @param cells Neighbor cell structure.
261 * The current cell information is valid if the current cell ID is
262 * not set to LTE_LC_CELL_EUTRAN_ID_INVALID.
263 *
264 * @return Zero on success or (negative) error code otherwise.
265 * @retval 1 Measurement failure.
266 * @retval -E2BIG The static buffers set by CONFIG_LTE_NEIGHBOR_CELLS_MAX
267 * are too small for the modem response. The associated data is still valid,
268 * but not complete.
269 */
271 const char *at_response, struct lte_lc_cells_info *cells);
272
273/* @brief Parses an XMODEMSLEEP response and extracts the sleep type and time.
274 *
275 * @note If the time parameter -1 after this API call, time shall be considered infinite.
276 *
277 * @param at_response Pointer to buffer with AT response.
278 * @param modem_sleep Pointer to a structure holding modem sleep data.
279 *
280 * @return Zero on success or (negative) error code otherwise.
281 */
282int parse_xmodemsleep(const char *at_response, struct lte_lc_modem_sleep *modem_sleep);
283
284/* @brief Parses a CONEVAL response and populates a struct with parameters from the response.
285 *
286 * @param at_response Pointer to buffer with AT response.
287 * @param params Pointer to a structure that will be populated with CONEVAL parameters.
288 *
289 * @return Zero on success, negative errno code if the API call fails, and a positive error
290 * code if the API call succeeds but connection evalution fails due to modem/network related
291 * reasons.
292 *
293 * @retval 0 Evaluation succeeded.
294 * @retval 1 Evaluation failed, no cell available.
295 * @retval 2 Evaluation failed, UICC not available.
296 * @retval 3 Evaluation failed, only barred cells available.
297 * @retval 4 Evaluation failed, radio busy (e.g GNSS activity)
298 * @retval 5 Evaluation failed, aborted due to higher priority operation.
299 * @retval 6 Evaluation failed, UE not registered to network.
300 * @retval 7 Evaluation failed, Unspecified.
301 */
302int parse_coneval(const char *at_response, struct lte_lc_conn_eval_params *params);
303
304/* @brief Parses an MDMEV response and populates an enum with the corresponding
305 * modem event type.
306 *
307 * @param at_response Pointer to buffer with AT response.
308 * @param modem_evt Pointer to enum to hold modem event.
309 *
310 * @return Zero on success, negative errno code on failure.
311 *
312 * @retval 0 Parsing succeeded.
313 * @retval -EIO If the AT response is not a valid MDMEV response.
314 * @retval -ENODATA If no modem event type was found in the AT response.
315 */
316int parse_mdmev(const char *at_response, enum lte_lc_modem_evt *modem_evt);
317
318/* @brief Parse a RAI response and extract RAI configuration.
319 *
320 * @param at_response AT response.
321 * @param rai_cfg RAI configuration.
322 *
323 * @return Zero on success, negative errno code on failure.
324 */
325int parse_rai(const char *at_response, struct lte_lc_rai_cfg *rai_cfg);
326
327/* @brief Add the handler in the event handler list if not already present.
328 *
329 * @param handler Event handler.
330 *
331 * @return Zero on success, negative errno code if the API call fails.
332 */
334
335/* @brief Remove the handler from the event handler list if present.
336 *
337 * @param handler Event handler.
338 *
339 * @return Zero on success, negative errno code if the API call fails.
340 */
342
343/* @brief Dispatch events for the registered event handlers.
344 *
345 * @param evt Event.
346 *
347 * @return Zero on success, negative errno code if the API call fails.
348 */
349void event_handler_list_dispatch(const struct lte_lc_evt *const evt);
350
351/* @brief Test if the handler list is empty.
352 *
353 * @return a boolean, true if it's empty, false otherwise
354 */
356
357/* @brief Convert string to integer with a chosen base.
358 *
359 * @param str_buf Pointer to null-terminated string.
360 * @param base The base to use when converting the string.
361 * @param output Pointer to an integer where the result is stored.
362 *
363 * @retval 0 if conversion was successful.
364 * @retval -ENODATA if conversion failed.
365 */
366int string_to_int(const char *str_buf, int base, int *output);
367
368/* @brief Get periodic search pattern string to be used in AT%PERIODICSEARCHCONF from
369 * a pattern struct.
370 *
371 * @param buf Buffer to store the string.
372 * @param buf_size Size of the provided buffer.
373 * @param pattern Pointer to pattern struct.
374 *
375 * @return Pointer to the buffer where the pattern string is stored.
376 */
377char *periodic_search_pattern_get(char *const buf, size_t buf_size,
378 const struct lte_lc_periodic_search_pattern *const pattern);
379
380/* @brief Parse a periodic search pattern from an AT%PERIODICSEARCHCONF response
381 * and populate a pattern struct with the result.
382 * The pattern string is expected to be without quotation marks and null-terminated.
383 *
384 * @param pattern_str Pointer to pattern string.
385 * @param pattern Pointer to storage for the parsed pattern.
386 *
387 * @retval 0 if parsing was successful.
388 * @retval -EBADMSG if pattern could not be parsed.
389 */
390int parse_periodic_search_pattern(const char *const pattern_str,
391 struct lte_lc_periodic_search_pattern *pattern);
392
393/* @brief Set RAI based on @kconfig{CONFIG_LTE_RAI_REQ}.
394 *
395 * If enabling of RAI is requested, AT%RAI=2 is used to order unsolicited RAI notifications.
396 * If setting that fails, AT%RAI=1 is used.
397 *
398 * @retval 0 Setting RAI succeeded.
399 * @retval -EFAULT Setting RAI failed.
400 */
401int rai_set(void);
static const struct event_proxy_config cfg
Definition: event_proxy_def.h:28
lte_lc_lte_mode
Definition: lte_lc.h:89
lte_lc_modem_evt
Definition: lte_lc.h:668
void(* lte_lc_evt_handler_t)(const struct lte_lc_evt *const evt)
Definition: lte_lc.h:1242
lte_lc_rrc_mode
Definition: lte_lc.h:332
lte_lc_nw_reg_status
Definition: lte_lc.h:33
int string_to_int(const char *str_buf, int base, int *output)
int parse_xt3412(const char *at_response, uint64_t *time)
int parse_coneval(const char *at_response, struct lte_lc_conn_eval_params *params)
bool event_handler_list_is_empty(void)
int parse_rrc_mode(const char *at_response, enum lte_lc_rrc_mode *mode, size_t mode_index)
int encode_psm(char *tau_ext_str, char *active_time_str, int rptau, int rat)
uint32_t neighborcell_count_get(const char *at_response)
int parse_cereg(const char *at_response, enum lte_lc_nw_reg_status *reg_status, struct lte_lc_cell *cell, enum lte_lc_lte_mode *lte_mode, struct lte_lc_psm_cfg *psm_cfg)
int parse_ncellmeas_gci(struct lte_lc_ncellmeas_params *params, const char *at_response, struct lte_lc_cells_info *cells)
int parse_mdmev(const char *at_response, enum lte_lc_modem_evt *modem_evt)
int parse_ncellmeas(const char *at_response, struct lte_lc_cells_info *cells)
int parse_rai(const char *at_response, struct lte_lc_rai_cfg *rai_cfg)
void event_handler_list_dispatch(const struct lte_lc_evt *const evt)
int parse_psm(const char *active_time_str, const char *tau_ext_str, const char *tau_legacy_str, struct lte_lc_psm_cfg *psm_cfg)
int parse_periodic_search_pattern(const char *const pattern_str, struct lte_lc_periodic_search_pattern *pattern)
int rai_set(void)
char * periodic_search_pattern_get(char *const buf, size_t buf_size, const struct lte_lc_periodic_search_pattern *const pattern)
int parse_xmodemsleep(const char *at_response, struct lte_lc_modem_sleep *modem_sleep)
int parse_edrx(const char *at_response, struct lte_lc_edrx_cfg *cfg, char *edrx_str, char *ptw_str)
int event_handler_list_remove_handler(lte_lc_evt_handler_t handler)
int event_handler_list_append_handler(lte_lc_evt_handler_t handler)
Definition: lte_lc.h:415
Definition: lte_lc.h:513
Definition: lte_lc.h:770
Definition: lte_lc.h:350
Definition: lte_lc.h:1190
Definition: lte_lc.h:563
Definition: lte_lc.h:992
Definition: lte_lc.h:1117
Definition: lte_lc.h:341
Definition: lte_lc.h:751