Mistake on this page?
Report an issue in GitHub or email us
ATCmdParser.h
1 /* Copyright (c) 2017-2019 ARM Limited
2  * SPDX-License-Identifier: Apache-2.0
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * @section DESCRIPTION
17  *
18  * Parser for the AT command syntax
19  *
20  */
21 #ifndef MBED_ATCMDPARSER_H
22 #define MBED_ATCMDPARSER_H
23 
24 #include <cstdarg>
25 #include "platform/Callback.h"
26 #include "platform/NonCopyable.h"
27 #include "platform/FileHandle.h"
28 
29 namespace mbed {
30 /** \addtogroup platform-public-api Platform */
31 /** @{*/
32 /**
33  * \defgroup platform_ATCmdParser ATCmdParser class
34  * @{
35  */
36 
37 /**
38  * Parser class for parsing AT commands
39  *
40  * Here are some examples:
41  * @code
42  * UARTSerial serial = UARTSerial(D1, D0);
43  * ATCmdParser at = ATCmdParser(&serial, "\r\n");
44  * int value;
45  * char buffer[100];
46  *
47  * at.send("AT") && at.recv("OK");
48  * at.send("AT+CWMODE=%d", 3) && at.recv("OK");
49  * at.send("AT+CWMODE?") && at.recv("+CWMODE:%d\r\nOK", &value);
50  * at.recv("+IPD,%d:", &value);
51  * at.read(buffer, value);
52  * at.recv("OK");
53  * @endcode
54  */
55 
56 class ATCmdParser : private NonCopyable<ATCmdParser> {
57 private:
58  // File handle
59  // Not owned by ATCmdParser
60  FileHandle *_fh;
61 
62  int _buffer_size;
63  char *_buffer;
64  int _timeout;
65 
66  // Parsing information
67  const char *_output_delimiter;
68  int _output_delim_size;
69  int _oob_cb_count;
70  char _in_prev;
71  bool _dbg_on;
72  bool _aborted;
73 
74  struct oob {
75  unsigned len;
76  const char *prefix;
78  oob *next;
79  };
80  oob *_oobs;
81 
82  /**
83  * Receive an AT response
84  *
85  * Receives a formatted response using scanf style formatting
86  * @see scanf
87  *
88  * Responses are parsed line at a time.
89  * If multiline is set to false parse only one line otherwise parse multiline response
90  * Any received data that does not match the response is ignored until
91  * a timeout occurs.
92  *
93  * @param response scanf-like format string of response to expect
94  * @param ... all scanf-like arguments to extract from response
95  * @param multiline determinate if parse one or multiple lines.
96  * @return number of bytes read or -1 on failure
97  */
98  int vrecvscanf(const char *response, std::va_list args, bool multiline);
99 
100 public:
101 
102  /**
103  * Constructor
104  *
105  * @param fh A FileHandle to the digital interface, used for AT commands
106  * @param output_delimiter End of command-line termination
107  * @param buffer_size Size of internal buffer for transaction
108  * @param timeout Timeout of the connection
109  * @param debug Turns on/off debug output for AT commands
110  */
111  ATCmdParser(FileHandle *fh, const char *output_delimiter = "\r",
112  int buffer_size = 256, int timeout = 8000, bool debug = false)
113  : _fh(fh), _buffer_size(buffer_size), _oob_cb_count(0), _in_prev(0), _aborted(false), _oobs(NULL)
114  {
115  _buffer = new char[buffer_size];
116  set_timeout(timeout);
117  set_delimiter(output_delimiter);
118  debug_on(debug);
119  }
120 
121  /**
122  * Destructor
123  */
125  {
126  while (_oobs) {
127  struct oob *oob = _oobs;
128  _oobs = oob->next;
129  delete oob;
130  }
131  delete[] _buffer;
132  }
133 
134  /**
135  * Allows timeout to be changed between commands
136  *
137  * @param timeout ATCmdParser APIs (read/write/send/recv ..etc) throw an
138  * error if no response is received in `timeout` duration
139  */
140  void set_timeout(int timeout)
141  {
142  _timeout = timeout;
143  }
144 
145  /**
146  * For backward compatibility.
147  * @deprecated Do not use this function. This function has been replaced with set_timeout for consistency.
148  *
149  * Please use set_timeout(int) API only from now on.
150  * Allows timeout to be changed between commands
151  *
152  * @param timeout ATCmdParser APIs (read/write/send/recv ..etc) throw an
153  * error if no response is received in `timeout` duration
154  *
155  */
156  MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with set_timeout for consistency")
157  void setTimeout(int timeout)
158  {
159  set_timeout(timeout);
160  }
161 
162  /**
163  * Sets string of characters to use as line delimiters
164  *
165  * @param output_delimiter String of characters to use as line delimiters
166  */
167  void set_delimiter(const char *output_delimiter)
168  {
169  _output_delimiter = output_delimiter;
170  _output_delim_size = strlen(output_delimiter);
171  }
172 
173  /**
174  * For backwards compatibility.
175  * @deprecated Do not use this function. This function has been replaced with set_delimiter for consistency.
176  *
177  * Please use set_delimiter(const char *) API only from now on.
178  * Sets string of characters to use as line delimiters
179  *
180  * @param output_delimiter string of characters to use as line delimiters
181  */
182  MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with set_delimiter for consistency")
183  void setDelimiter(const char *output_delimiter)
184  {
185  set_delimiter(output_delimiter);
186  }
187 
188  /**
189  * Allows traces from modem to be turned on or off
190  *
191  * @param on Set as 1 to turn on traces and 0 to disable traces.
192  */
193  void debug_on(uint8_t on)
194  {
195  _dbg_on = (on) ? 1 : 0;
196  }
197 
198  /**
199  * For backward compatibility.
200  * @deprecated Do not use this function. This function has been replaced with debug_on for consistency.
201  *
202  * Allows traces from modem to be turned on or off
203  *
204  * @param on Set as 1 to turn on traces and 0 to disable traces.
205  */
206  MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with debug_on for consistency")
207  void debugOn(uint8_t on)
208  {
209  debug_on(on);
210  }
211 
212  /**
213  * Sends an AT command
214  *
215  * Sends a formatted command using printf style formatting
216  * @see printf
217  *
218  * @param command printf-like format string of command to send which
219  * is appended with a newline
220  * @param ... all printf-like arguments to insert into command
221  * @return true only if command is successfully sent
222  */
223  bool send(const char *command, ...) MBED_PRINTF_METHOD(1, 2);
224 
225  bool vsend(const char *command, std::va_list args);
226 
227  /**
228  * Receive an AT response
229  *
230  * Receives a formatted response using scanf style formatting
231  * @see scanf
232  *
233  * Responses are parsed line at a time.
234  * Any received data that does not match the response is ignored until
235  * a timeout occurs.
236  *
237  * @param response scanf-like format string of response to expect
238  * @param ... all scanf-like arguments to extract from response
239  * @return true only if response is successfully matched
240  */
241  bool recv(const char *response, ...) MBED_SCANF_METHOD(1, 2);
242 
243  bool vrecv(const char *response, std::va_list args);
244 
245  /**
246  * Write a single byte to the underlying stream
247  *
248  * @param c The byte to write
249  * @return The byte that was written or -1 during a timeout
250  */
251  int putc(char c);
252 
253  /**
254  * Get a single byte from the underlying stream
255  *
256  * @return The byte that was read or -1 during a timeout
257  */
258  int getc();
259 
260  /**
261  * Write an array of bytes to the underlying stream
262  *
263  * @param data The array of bytes to write
264  * @param size Number of bytes to write
265  * @return number of bytes written or -1 on failure
266  */
267  int write(const char *data, int size);
268 
269  /**
270  * Read an array of bytes from the underlying stream
271  *
272  * @param data The buffer for filling the read bytes
273  * @param size Number of bytes to read
274  * @return number of bytes read or -1 on failure
275  */
276  int read(char *data, int size);
277 
278  /**
279  * Direct printf to underlying stream
280  * @see printf
281  *
282  * @param format Format string to pass to printf
283  * @param ... Variable arguments to printf
284  * @return number of bytes written or -1 on failure
285  */
286  int printf(const char *format, ...) MBED_PRINTF_METHOD(1, 2);
287 
288  int vprintf(const char *format, std::va_list args);
289 
290  /**
291  * Direct scanf on underlying stream
292  * This function does not itself match whitespace in its format string, so \n is not significant to it.
293  * It should be used only when certain string is needed or format ends with certain character, otherwise
294  * it will fill the output with one character.
295  * @see scanf
296  *
297  * @param format Format string to pass to scanf
298  * @param ... Variable arguments to scanf
299  * @return number of bytes read or -1 on failure
300  */
301  int scanf(const char *format, ...) MBED_SCANF_METHOD(1, 2);
302 
303  int vscanf(const char *format, std::va_list args);
304 
305  /**
306  * Attach a callback for out-of-band data
307  *
308  * @param prefix String on when to initiate callback
309  * @param func Callback to call when string is read
310  * @note out-of-band data is only processed during a scanf call
311  */
312  void oob(const char *prefix, mbed::Callback<void()> func);
313 
314  /**
315  * Flushes the underlying stream
316  */
317  void flush();
318 
319  /**
320  * Abort current recv
321  *
322  * Can be called from out-of-band handler to interrupt the current
323  * recv operation.
324  */
325  void abort();
326 
327  /**
328  * Process out-of-band data
329  *
330  * Process out-of-band data in the receive buffer. This function
331  * returns immediately if there is no data to process.
332  *
333  * @return true if out-of-band data processed, false otherwise
334  */
335  bool process_oob(void);
336 };
337 
338 /**@}*/
339 
340 /**@}*/
341 
342 } //namespace mbed
343 
344 #endif //MBED_ATCMDPARSER_H
void debug_on(uint8_t on)
Allows traces from modem to be turned on or off.
Definition: ATCmdParser.h:193
void setTimeout(int timeout)
For backward compatibility.
Definition: ATCmdParser.h:157
int getc()
Get a single byte from the underlying stream.
void set_timeout(int timeout)
Allows timeout to be changed between commands.
Definition: ATCmdParser.h:140
int scanf(const char *format,...) MBED_SCANF_METHOD(1
Direct scanf on underlying stream This function does not itself match whitespace in its format string...
Class FileHandle.
Definition: FileHandle.h:46
int putc(char c)
Write a single byte to the underlying stream.
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:169
void abort()
Abort current recv.
ATCmdParser(FileHandle *fh, const char *output_delimiter="\r", int buffer_size=256, int timeout=8000, bool debug=false)
Constructor.
Definition: ATCmdParser.h:111
void oob(const char *prefix, mbed::Callback< void()> func)
Attach a callback for out-of-band data.
bool recv(const char *response,...) MBED_SCANF_METHOD(1
Receive an AT response.
void debugOn(uint8_t on)
For backward compatibility.
Definition: ATCmdParser.h:207
int write(const char *data, int size)
Write an array of bytes to the underlying stream.
void set_delimiter(const char *output_delimiter)
Sets string of characters to use as line delimiters.
Definition: ATCmdParser.h:167
~ATCmdParser()
Destructor.
Definition: ATCmdParser.h:124
void flush()
Flushes the underlying stream.
Parser class for parsing AT commands.
Definition: ATCmdParser.h:56
static void debug(const char *format,...) MBED_PRINTF(1
Output a debug message.
Definition: mbed_debug.h:44
bool process_oob(void)
Process out-of-band data.
int read(char *data, int size)
Read an array of bytes from the underlying stream.
int printf(const char *format,...) MBED_PRINTF_METHOD(1
Direct printf to underlying stream.
bool send(const char *command,...) MBED_PRINTF_METHOD(1
Sends an AT command.
#define MBED_DEPRECATED_SINCE(D, M)
MBED_DEPRECATED("message string") Mark a function declaration as deprecated, if it used then a warnin...
void setDelimiter(const char *output_delimiter)
For backwards compatibility.
Definition: ATCmdParser.h:183
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.