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  * BufferedSerial serial = BufferedSerial(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  * Sets string of characters to use as line delimiters
147  *
148  * @param output_delimiter String of characters to use as line delimiters
149  */
150  void set_delimiter(const char *output_delimiter)
151  {
152  _output_delimiter = output_delimiter;
153  _output_delim_size = strlen(output_delimiter);
154  }
155 
156  /**
157  * Allows traces from modem to be turned on or off
158  *
159  * @param on Set as 1 to turn on traces and 0 to disable traces.
160  */
161  void debug_on(uint8_t on)
162  {
163  _dbg_on = (on) ? 1 : 0;
164  }
165 
166  /**
167  * Sends an AT command
168  *
169  * Sends a formatted command using printf style formatting
170  * @see printf
171  *
172  * @param command printf-like format string of command to send which
173  * is appended with a newline
174  * @param ... all printf-like arguments to insert into command
175  * @return true only if command is successfully sent
176  */
177  bool send(const char *command, ...) MBED_PRINTF_METHOD(1, 2);
178 
179  bool vsend(const char *command, std::va_list args);
180 
181  /**
182  * Receive an AT response
183  *
184  * Receives a formatted response using scanf style formatting
185  * @see scanf
186  *
187  * Responses are parsed line at a time.
188  * Any received data that does not match the response is ignored until
189  * a timeout occurs.
190  *
191  * @param response scanf-like format string of response to expect
192  * @param ... all scanf-like arguments to extract from response
193  * @return true only if response is successfully matched
194  */
195  bool recv(const char *response, ...) MBED_SCANF_METHOD(1, 2);
196 
197  bool vrecv(const char *response, std::va_list args);
198 
199  /**
200  * Write a single byte to the underlying stream
201  *
202  * @param c The byte to write
203  * @return The byte that was written or -1 during a timeout
204  */
205  int putc(char c);
206 
207  /**
208  * Get a single byte from the underlying stream
209  *
210  * @return The byte that was read or -1 during a timeout
211  */
212  int getc();
213 
214  /**
215  * Write an array of bytes to the underlying stream
216  *
217  * @param data The array of bytes to write
218  * @param size Number of bytes to write
219  * @return number of bytes written or -1 on failure
220  */
221  int write(const char *data, int size);
222 
223  /**
224  * Read an array of bytes from the underlying stream
225  *
226  * @param data The buffer for filling the read bytes
227  * @param size Number of bytes to read
228  * @return number of bytes read or -1 on failure
229  */
230  int read(char *data, int size);
231 
232  /**
233  * Direct printf to underlying stream
234  * @see printf
235  *
236  * @param format Format string to pass to printf
237  * @param ... Variable arguments to printf
238  * @return number of bytes written or -1 on failure
239  */
240  int printf(const char *format, ...) MBED_PRINTF_METHOD(1, 2);
241 
242  int vprintf(const char *format, std::va_list args);
243 
244  /**
245  * Direct scanf on underlying stream
246  * This function does not itself match whitespace in its format string, so \n is not significant to it.
247  * It should be used only when certain string is needed or format ends with certain character, otherwise
248  * it will fill the output with one character.
249  * @see scanf
250  *
251  * @param format Format string to pass to scanf
252  * @param ... Variable arguments to scanf
253  * @return number of bytes read or -1 on failure
254  */
255  int scanf(const char *format, ...) MBED_SCANF_METHOD(1, 2);
256 
257  int vscanf(const char *format, std::va_list args);
258 
259  /**
260  * Attach a callback for out-of-band data
261  *
262  * @param prefix String on when to initiate callback
263  * @param func Callback to call when string is read
264  * @note out-of-band data is only processed during a scanf call
265  */
266  void oob(const char *prefix, mbed::Callback<void()> func);
267 
268  /**
269  * @brief remove_oob Removes oob callback handler
270  * @param prefix Prefix to identify oob to be removed.
271  */
272  void remove_oob(const char *prefix);
273 
274  /**
275  * Flushes the underlying stream
276  */
277  void flush();
278 
279  /**
280  * Abort current recv
281  *
282  * Can be called from out-of-band handler to interrupt the current
283  * recv operation.
284  */
285  void abort();
286 
287  /**
288  * Process out-of-band data
289  *
290  * Process out-of-band data in the receive buffer. This function
291  * returns immediately if there is no data to process.
292  *
293  * @return true if out-of-band data processed, false otherwise
294  */
295  bool process_oob(void);
296 };
297 
298 /**@}*/
299 
300 /**@}*/
301 
302 } //namespace mbed
303 
304 #endif //MBED_ATCMDPARSER_H
void debug_on(uint8_t on)
Allows traces from modem to be turned on or off.
Definition: ATCmdParser.h:161
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...
void remove_oob(const char *prefix)
remove_oob Removes oob callback handler
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:162
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.
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:150
~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.
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.