Skip to content

Commit 89d631e

Browse files
MirkoCovizzib-gent
authored andcommitted
lib: add at_parser library
* Introduces the `at_parser` library for parsing AT command responses, notifications, or events. It exports an API that lets the user iterate through an AT command string and retrieve any of its elements based on their indices, efficiently and without heap allocations. Under the hood, this library leverages the power of regular expressions converted to deterministic finite automata by the free and open-source lexer generator `re2c`. * In the `at_cmd_parser` library, renames the function `at_parser_cmd_type_get` to `at_parser_at_cmd_type_get` to prevent name collisions with the function `at_parser_cmd_type_get` in the `at_parser` library. * Deprecates the `at_cmd_parser` library. It will be removed in a future version. Signed-off-by: Mirko Covizzi <[email protected]> Co-authored-by: Bartosz Gentkowski <[email protected]>
1 parent 1f800bf commit 89d631e

File tree

25 files changed

+4615
-11
lines changed

25 files changed

+4615
-11
lines changed

CODEOWNERS

+2
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ Kconfig* @tejlmand
111111
/lib/boot_banner/ @nordicjm
112112
/lib/adp536x/ @nrfconnect/ncs-cia
113113
/lib/at_cmd_parser/ @rlubos
114+
/lib/at_parser/ @MirkoCovizzi
114115
/lib/at_cmd_custom/ @eivindj-nordic
115116
/lib/at_host/ @rlubos
116117
/lib/at_monitor/ @lemrey @rlubos
@@ -313,6 +314,7 @@ Kconfig* @tejlmand
313314
/tests/drivers/nrfx_integration_test/ @anangl
314315
/tests/drivers/pwm/gpio_loopback/ @nrfconnect/ncs-low-level-test
315316
/tests/lib/at_cmd_parser/ @rlubos
317+
/tests/lib/at_parser/ @MirkoCovizzi
316318
/tests/lib/at_cmd_custom/ @eivindj-nordic
317319
/tests/lib/date_time/ @trantanen @tokangas
318320
/tests/lib/edge_impulse/ @pdunaj @MarekPieta

applications/serial_lte_modem/src/slm_at_host.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ int slm_at_cb_wrapper(char *buf, size_t len, char *at_cmd, slm_at_callback *cb)
871871
if (err) {
872872
return err;
873873
}
874-
err = cb(at_parser_cmd_type_get(at_cmd), list, at_params_valid_count_get(list));
874+
err = cb(at_parser_at_cmd_type_get(at_cmd), list, at_params_valid_count_get(list));
875875
if (!err) {
876876
err = at_cmd_custom_respond(buf, len, "OK\r\n");
877877
if (err) {

doc/nrf/libraries/modem/at_cmd_parser.rst

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ AT command parser
77
:local:
88
:depth: 2
99

10+
.. note::
11+
12+
This library is deprecated in favor of the :ref:`at_parser_readme` library.
13+
1014
The AT command parser is a library which parses any of the following:
1115

1216
* A string response returned after issuing an AT command

doc/nrf/libraries/modem/at_parser.rst

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
.. _at_parser_readme:
2+
3+
AT parser
4+
#########
5+
6+
.. contents::
7+
:local:
8+
:depth: 2
9+
10+
The AT parser is a library that parses AT command responses, notifications, and events.
11+
12+
Overview
13+
========
14+
15+
The library exports an API that lets the user iterate through an AT command string and retrieve any of its elements based on their indices, efficiently and without heap allocations.
16+
Under the hood, this library uses regular expressions converted to deterministic finite automata by the free and open-source lexer generator ``re2c``.
17+
18+
Configuration
19+
=============
20+
21+
To begin using the AT parser, you first need to initialize it.
22+
This is done by invoking the :c:func:`at_parser_init` function, where you provide a pointer to the AT parser and the AT command string that needs to be parsed.
23+
24+
The following code snippet shows how to initialize the AT parser for an AT command response:
25+
26+
.. code-block:: c
27+
28+
int err;
29+
struct at_parser parser;
30+
const char *at_response = "+CFUN: 1";
31+
32+
err = at_parser_init(&parser, at_response);
33+
if (err) {
34+
return err;
35+
}
36+
37+
Usage
38+
=====
39+
40+
Based on the type of the element at a given index, you can obtain its value by calling the type-generic macro :c:macro:`at_parser_num_get` for integer values, or the function :c:func:`at_params_string_get` for string values.
41+
42+
The following code snippet shows how to retrieve the prefix, a ``uint16_t`` value, and a string value from an AT command response using the AT parser:
43+
44+
.. code-block:: c
45+
46+
int err;
47+
struct at_parser parser;
48+
const char *at_response = "+CGCONTRDP: 0,,\"internet\",\"\",\"\",\"10.0.0.1\",\"10.0.0.2\",,,,,1028";
49+
uint16_t num;
50+
char buffer[16] = { 0 };
51+
size_t len = sizeof(buffer);
52+
53+
err = at_parser_init(&parser, at_response);
54+
if (err) {
55+
return err;
56+
}
57+
58+
/* Retrieve the AT command response prefix, at index 0 of the AT command string. */
59+
err = at_parser_string_get(&parser, 0, buffer, &len);
60+
if (err) {
61+
return err;
62+
}
63+
64+
/* "Prefix: `+CGCONTRDP`" */
65+
printk("Prefix: `%s`\n", buffer);
66+
67+
/* Retrieve the first subparameter, at index 1 of the AT command string.
68+
* `at_parser_num_get` is a type-generic macro that retrieves an integer based on the type
69+
* of the passed variable. In this example, the preprocessor will expand the macro to the
70+
* function corresponding to the `uint16_t` type, which is the function `at_parser_uint16_get`.
71+
*/
72+
err = at_parser_num_get(&parser, 1, &num);
73+
if (err) {
74+
return err;
75+
}
76+
77+
/* "First subparameter: 0" */
78+
printk("First subparameter: %u\n", num);
79+
80+
/* Reset the buffer length. */
81+
len = sizeof(buffer);
82+
83+
/* Retrieve the third subparameter, at index 3 of the AT command string. */
84+
err = at_parser_string_get(&parser, 3, buffer, &len);
85+
if (err) {
86+
return err;
87+
}
88+
89+
/* "Third subparameter: `internet`" */
90+
printk("Third subparameter: `%s`\n", buffer);
91+
92+
API documentation
93+
*****************
94+
95+
| Header file: :file:`include/modem/at_parser.h`
96+
| Source file: :file:`lib/at_parser/src/at_parser.c`
97+
98+
.. doxygengroup:: at_parser
99+
:project: nrf
100+
:members:

doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst

+197-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ LTE link control library
5555
Use the :kconfig:option:`CONFIG_LTE_NETWORK_MODE_LTE_M_NBIOT` or :kconfig:option:`CONFIG_LTE_NETWORK_MODE_LTE_M_NBIOT_GPS` Kconfig option instead.
5656
In addition, you can control the priority between LTE-M and NB-IoT using the :kconfig:option:`CONFIG_LTE_MODE_PREFERENCE` Kconfig option.
5757

58+
AT command parser
59+
-----------------
60+
61+
.. toggle::
62+
63+
* The :c:func:`at_parser_cmd_type_get` has been renamed to :c:func:`at_parser_at_cmd_type_get`.
64+
5865
.. _migration_2.8_recommended:
5966

6067
Recommended changes
@@ -74,4 +81,193 @@ Libraries
7481

7582
This section describes the changes related to libraries.
7683

77-
|no_changes_yet_note|
84+
AT command parser
85+
-----------------
86+
87+
.. toggle::
88+
89+
* The :ref:`at_cmd_parser_readme` library has been deprecated in favor of the :ref:`at_parser_readme` library and will be removed in a future version.
90+
91+
You can follow this guide to migrate your application to use the :ref:`at_parser_readme` library.
92+
This will reduce the footprint of the application and will decrease memory requirements on the heap.
93+
94+
To replace :ref:`at_cmd_parser_readme` with the :ref:`at_parser_readme`, complete the following steps:
95+
96+
1. Replace the :kconfig:option:`CONFIG_AT_CMD_PARSER` Kconfig option with the :kconfig:option:`CONFIG_AT_PARSER` Kconfig option.
97+
98+
#. Replace header files:
99+
100+
* Remove:
101+
102+
.. code-block:: C
103+
104+
#include <modem/at_cmd_parser.h>
105+
#include <modem/at_params.h>
106+
107+
* Add:
108+
109+
.. code-block:: C
110+
111+
#include <modem/at_parser.h>
112+
113+
#. Replace AT parameter list:
114+
115+
* Remove:
116+
117+
.. code-block:: C
118+
119+
struct at_param_list param_list;
120+
121+
* Add:
122+
123+
.. code-block:: C
124+
125+
struct at_parser parser;
126+
127+
#. Replace AT parameter list initialization:
128+
129+
* Remove:
130+
131+
.. code-block:: C
132+
133+
/* `param_list` is a pointer to the AT parameter list.
134+
* `AT_PARAMS_COUNT` is the maximum number of parameters of the list.
135+
*/
136+
at_params_list_init(&param_list, AT_PARAMS_COUNT);
137+
138+
/* Other code. */
139+
140+
/* `at_string` is the AT command string to be parsed.
141+
* `&remainder` is a pointer to the returned remainder after parsing.
142+
* `&param_list` is a pointer to the AT parameter list.
143+
*/
144+
at_parser_params_from_str(at_string, &remainder, &param_list);
145+
146+
* Add:
147+
148+
.. code-block:: C
149+
150+
/* `&at_parser` is a pointer to the AT parser.
151+
* `at_string` is the AT command string to be parsed.
152+
*/
153+
at_parser_init(&at_parser, at_string);
154+
155+
.. note::
156+
157+
Remember to check the returned error codes from the :ref:`at_parser_readme` functions.
158+
For the sake of simplicity, they have been omitted in this migration guide.
159+
Refer to the :ref:`at_parser_readme` documentation for more information on the API and the returned error codes.
160+
161+
#. Replace integer parameter retrieval:
162+
163+
* Remove:
164+
165+
.. code-block:: C
166+
167+
int value;
168+
169+
/* `&param_list` is a pointer to the AT parameter list.
170+
* `index` is the index of the parameter to retrieve.
171+
* `&value` is a pointer to the output integer variable.
172+
*/
173+
at_params_int_get(&param_list, index, &value);
174+
175+
uint16_t value;
176+
at_params_unsigned_short_get(&param_list, index, &value);
177+
178+
/* Other variants: */
179+
at_params_short_get(&param_list, index, &value);
180+
at_params_unsigned_int_get(&param_list, index, &value);
181+
at_params_int64_get(&param_list, index, &value);
182+
183+
* Add:
184+
185+
.. code-block:: C
186+
187+
int value;
188+
189+
/* `&at_parser` is a pointer to the AT parser.
190+
* `index` is the index of the parameter to retrieve.
191+
* `&value` is a pointer to the output integer variable.
192+
*
193+
* Note: this function is type-generic on the type of the output integer variable.
194+
*/
195+
err = at_parser_num_get(&at_parser, index, &value);
196+
197+
uint16_t value;
198+
/* Note: this function is type-generic on the type of the output integer variable. */
199+
err = at_parser_num_get(&at_parser, index, &value);
200+
201+
#. Replace string parameter retrieval:
202+
203+
* Remove:
204+
205+
.. code-block:: C
206+
207+
/* `&param_list` is a pointer to the AT parameter list.
208+
* `index` is the index of the parameter to retrieve.
209+
* `value` is the output buffer where the string is copied into.
210+
* `&len` is a pointer to the length of the copied string.
211+
*
212+
* Note: the copied string is not null-terminated.
213+
*/
214+
at_params_string_get(&param_list, index, value, &len);
215+
216+
/* Null-terminate the string. */
217+
value[len] = '\0';
218+
219+
* Add:
220+
221+
.. code-block:: C
222+
223+
/* `&at_parser` is a pointer to the AT parser.
224+
* `index` is the index of the parameter to retrieve.
225+
* `value` is the output buffer where the string is copied into.
226+
* `&len` is a pointer to the length of the copied string.
227+
*
228+
* Note: the copied string is null-terminated.
229+
*/
230+
at_parser_string_get(&at_parser, index, value, &len);
231+
232+
#. Replace parameter count retrieval:
233+
234+
* Remove:
235+
236+
.. code-block:: C
237+
238+
/* `&param_list` is a pointer to the AT parameter list.
239+
* `count` is the returned parameter count.
240+
*/
241+
uint32_t count = at_params_valid_count_get(&param_list);
242+
243+
* Add:
244+
245+
.. code-block:: C
246+
247+
size_t count;
248+
249+
/* `&at_parser` is a pointer to the AT parser.
250+
* `&count` is a pointer to the returned parameter count.
251+
*/
252+
at_parser_cmd_count_get(&at_parser, &count);
253+
254+
#. Replace command type retrieval:
255+
256+
* Remove:
257+
258+
.. code-block:: C
259+
260+
/* `at_string` is the AT string that we want to retrieve the command type of.
261+
*/
262+
enum at_cmd_type type = at_parser_at_cmd_type_get(at_string);
263+
264+
* Add:
265+
266+
.. code-block:: C
267+
268+
enum at_parser_cmd_type type;
269+
270+
/* `&at_parser` is a pointer to the AT parser.
271+
* `&type` pointer to the returned command type.
272+
*/
273+
at_parser_cmd_type_get(&at_parser, &type);

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

+19
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,25 @@ Gazell libraries
482482
Modem libraries
483483
---------------
484484

485+
* Added:
486+
487+
* The :ref:`at_parser_readme` library.
488+
The :ref:`at_parser_readme` is a library that parses AT command responses, notifications, and events.
489+
Compared to the deprecated :ref:`at_cmd_parser_readme` library, it does not allocate memory dynamically and has a smaller footprint.
490+
For more information on how to transition from the :ref:`at_cmd_parser_readme` library to the :ref:`at_parser_readme` library, see the :ref:`migration guide <migration_2.8_recommended>`.
491+
492+
* :ref:`at_cmd_parser_readme` library:
493+
494+
* Deprecated:
495+
496+
* The :ref:`at_cmd_parser_readme` library in favor of the :ref:`at_parser_readme` library.
497+
The :ref:`at_cmd_parser_readme` library will be removed in a future version.
498+
For more information on how to transition from the :ref:`at_cmd_parser_readme` library to the :ref:`at_parser_readme` library, see the :ref:`migration guide <migration_2.8_recommended>`.
499+
* The :kconfig:option:`CONFIG_AT_CMD_PARSER`.
500+
This option will be removed in a future version.
501+
502+
* Renamed the :c:func:`at_parser_cmd_type_get` function to :c:func:`at_parser_at_cmd_type_get` to prevent a name collision.
503+
485504
* :ref:`lte_lc_readme` library:
486505

487506
* Removed:

include/modem/at_cmd_parser.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ enum at_cmd_type {
127127
*
128128
* @return Command type.
129129
*/
130-
enum at_cmd_type at_parser_cmd_type_get(const char *at_cmd);
130+
enum at_cmd_type at_parser_at_cmd_type_get(const char *at_cmd);
131131

132132
/** @} */
133133

0 commit comments

Comments
 (0)