Parser for AT commands and similar protocols

Dependencies:   BufferedSerial

Fork of ATParser by NetworkSocketAPI

Committer:
Raffaello
Date:
Mon May 22 18:05:51 2017 +0000
Revision:
16:8f98e042b9b4
Parent:
12:7d3c3f7ce928
Child:
17:f395d107f15e
Fixed read string from buffer. Now "%s" works.; Added different initialization start delimiter

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Christopher Haster 12:7d3c3f7ce928 1 /* Copyright (c) 2015 ARM Limited
Christopher Haster 12:7d3c3f7ce928 2 *
Christopher Haster 12:7d3c3f7ce928 3 * Licensed under the Apache License, Version 2.0 (the "License");
Christopher Haster 12:7d3c3f7ce928 4 * you may not use this file except in compliance with the License.
Christopher Haster 12:7d3c3f7ce928 5 * You may obtain a copy of the License at
Christopher Haster 12:7d3c3f7ce928 6 *
Christopher Haster 12:7d3c3f7ce928 7 * http://www.apache.org/licenses/LICENSE-2.0
Christopher Haster 12:7d3c3f7ce928 8 *
Christopher Haster 12:7d3c3f7ce928 9 * Unless required by applicable law or agreed to in writing, software
Christopher Haster 12:7d3c3f7ce928 10 * distributed under the License is distributed on an "AS IS" BASIS,
Christopher Haster 12:7d3c3f7ce928 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Christopher Haster 12:7d3c3f7ce928 12 * See the License for the specific language governing permissions and
Christopher Haster 12:7d3c3f7ce928 13 * limitations under the License.
Christopher Haster 12:7d3c3f7ce928 14 *
Christopher Haster 12:7d3c3f7ce928 15 * @section DESCRIPTION
Christopher Haster 12:7d3c3f7ce928 16 *
Christopher Haster 12:7d3c3f7ce928 17 * Parser for the AT command syntax
Christopher Haster 12:7d3c3f7ce928 18 *
Christopher Haster 12:7d3c3f7ce928 19 */
Christopher Haster 12:7d3c3f7ce928 20
Christopher Haster 12:7d3c3f7ce928 21 #include "mbed.h"
Christopher Haster 12:7d3c3f7ce928 22 #include <cstdarg>
Christopher Haster 12:7d3c3f7ce928 23 #include "BufferedSerial.h"
Christopher Haster 12:7d3c3f7ce928 24
Christopher Haster 12:7d3c3f7ce928 25
Christopher Haster 12:7d3c3f7ce928 26 /**
Christopher Haster 12:7d3c3f7ce928 27 * Parser class for parsing AT commands
Christopher Haster 12:7d3c3f7ce928 28 *
Christopher Haster 12:7d3c3f7ce928 29 * Here are some examples:
Christopher Haster 12:7d3c3f7ce928 30 * @code
Christopher Haster 12:7d3c3f7ce928 31 * ATParser at = ATParser(serial, "\r\n");
Christopher Haster 12:7d3c3f7ce928 32 * int value;
Christopher Haster 12:7d3c3f7ce928 33 * char buffer[100];
Christopher Haster 12:7d3c3f7ce928 34 *
Christopher Haster 12:7d3c3f7ce928 35 * at.send("AT") && at.recv("OK");
Christopher Haster 12:7d3c3f7ce928 36 * at.send("AT+CWMODE=%d", 3) && at.recv("OK");
Christopher Haster 12:7d3c3f7ce928 37 * at.send("AT+CWMODE?") && at.recv("+CWMODE:%d\r\nOK", &value);
Christopher Haster 12:7d3c3f7ce928 38 * at.recv("+IPD,%d:", &value);
Christopher Haster 12:7d3c3f7ce928 39 * at.read(buffer, value);
Christopher Haster 12:7d3c3f7ce928 40 * at.recv("OK");
Christopher Haster 12:7d3c3f7ce928 41 * @endcode
Christopher Haster 12:7d3c3f7ce928 42 */
Christopher Haster 12:7d3c3f7ce928 43 class ATParser
Christopher Haster 12:7d3c3f7ce928 44 {
Christopher Haster 12:7d3c3f7ce928 45 private:
Christopher Haster 12:7d3c3f7ce928 46 // Serial information
Christopher Haster 12:7d3c3f7ce928 47 BufferedSerial *_serial;
Christopher Haster 12:7d3c3f7ce928 48 int _buffer_size;
Christopher Haster 12:7d3c3f7ce928 49 char *_buffer;
Christopher Haster 12:7d3c3f7ce928 50 int _timeout;
Christopher Haster 12:7d3c3f7ce928 51
Christopher Haster 12:7d3c3f7ce928 52 // Parsing information
Raffaello 16:8f98e042b9b4 53 const char *_delimiter_send;
Raffaello 16:8f98e042b9b4 54 const char *_delimiter_close;
Raffaello 16:8f98e042b9b4 55 int _delim_size_send;
Raffaello 16:8f98e042b9b4 56 int _delim_size_close;
Raffaello 16:8f98e042b9b4 57 int _delim_check;
Christopher Haster 12:7d3c3f7ce928 58 bool dbg_on;
Christopher Haster 12:7d3c3f7ce928 59
Christopher Haster 12:7d3c3f7ce928 60 public:
Christopher Haster 12:7d3c3f7ce928 61 /**
Christopher Haster 12:7d3c3f7ce928 62 * Constructor
Christopher Haster 12:7d3c3f7ce928 63 *
Christopher Haster 12:7d3c3f7ce928 64 * @param serial serial interface to use for AT commands
Christopher Haster 12:7d3c3f7ce928 65 * @param buffer_size size of internal buffer for transaction
Christopher Haster 12:7d3c3f7ce928 66 * @param timeout timeout of the connection
Christopher Haster 12:7d3c3f7ce928 67 * @param delimiter string of characters to use as line delimiters
Christopher Haster 12:7d3c3f7ce928 68 */
Christopher Haster 12:7d3c3f7ce928 69 ATParser(BufferedSerial &serial, const char *delimiter = "\r\n", int buffer_size = 256, int timeout = 8000, bool debug = false) :
Christopher Haster 12:7d3c3f7ce928 70 _serial(&serial),
Christopher Haster 12:7d3c3f7ce928 71 _buffer_size(buffer_size) {
Christopher Haster 12:7d3c3f7ce928 72 _buffer = new char[buffer_size];
Christopher Haster 12:7d3c3f7ce928 73 setTimeout(timeout);
Christopher Haster 12:7d3c3f7ce928 74 setDelimiter(delimiter);
Raffaello 16:8f98e042b9b4 75 setDelimiterSend(delimiter);
Christopher Haster 12:7d3c3f7ce928 76 debugOn(debug);
Christopher Haster 12:7d3c3f7ce928 77 }
Christopher Haster 12:7d3c3f7ce928 78
Christopher Haster 12:7d3c3f7ce928 79 /**
Christopher Haster 12:7d3c3f7ce928 80 * Destructor
Christopher Haster 12:7d3c3f7ce928 81 */
Christopher Haster 12:7d3c3f7ce928 82 ~ATParser() {
Christopher Haster 12:7d3c3f7ce928 83 delete [] _buffer;
Christopher Haster 12:7d3c3f7ce928 84 }
Christopher Haster 12:7d3c3f7ce928 85
Christopher Haster 12:7d3c3f7ce928 86 /**
Christopher Haster 12:7d3c3f7ce928 87 * Allows timeout to be changed between commands
Christopher Haster 12:7d3c3f7ce928 88 *
Christopher Haster 12:7d3c3f7ce928 89 * @param timeout timeout of the connection
Christopher Haster 12:7d3c3f7ce928 90 */
Christopher Haster 12:7d3c3f7ce928 91 void setTimeout(int timeout) {
Christopher Haster 12:7d3c3f7ce928 92 _timeout = timeout;
Christopher Haster 12:7d3c3f7ce928 93 }
Christopher Haster 12:7d3c3f7ce928 94
Christopher Haster 12:7d3c3f7ce928 95 /**
Christopher Haster 12:7d3c3f7ce928 96 * Sets string of characters to use as line delimiters
Christopher Haster 12:7d3c3f7ce928 97 *
Christopher Haster 12:7d3c3f7ce928 98 * @param delimiter string of characters to use as line delimiters
Christopher Haster 12:7d3c3f7ce928 99 */
Christopher Haster 12:7d3c3f7ce928 100 void setDelimiter(const char *delimiter) {
Raffaello 16:8f98e042b9b4 101 _delimiter_close = delimiter;
Raffaello 16:8f98e042b9b4 102 _delim_size_close = strlen(delimiter);
Christopher Haster 12:7d3c3f7ce928 103 }
Christopher Haster 12:7d3c3f7ce928 104
Christopher Haster 12:7d3c3f7ce928 105 /**
Raffaello 16:8f98e042b9b4 106 * Sets string of characters to use as line delimiters
Raffaello 16:8f98e042b9b4 107 *
Raffaello 16:8f98e042b9b4 108 * @param delimiter string of characters to use as line delimiters
Raffaello 16:8f98e042b9b4 109 */
Raffaello 16:8f98e042b9b4 110 void setDelimiterSend(const char *delimiter) {
Raffaello 16:8f98e042b9b4 111 _delimiter_send = delimiter;
Raffaello 16:8f98e042b9b4 112 _delim_size_send = strlen(delimiter);
Raffaello 16:8f98e042b9b4 113 }
Raffaello 16:8f98e042b9b4 114
Raffaello 16:8f98e042b9b4 115 /**
Christopher Haster 12:7d3c3f7ce928 116 * Allows echo to be on or off
Christopher Haster 12:7d3c3f7ce928 117 *
Christopher Haster 12:7d3c3f7ce928 118 * @param echo 1 for echo and 0 turns it off
Christopher Haster 12:7d3c3f7ce928 119 */
Christopher Haster 12:7d3c3f7ce928 120 void debugOn(uint8_t on) {
Christopher Haster 12:7d3c3f7ce928 121 dbg_on = (on) ? 1 : 0;
Christopher Haster 12:7d3c3f7ce928 122 }
Christopher Haster 12:7d3c3f7ce928 123
Christopher Haster 12:7d3c3f7ce928 124 /**
Christopher Haster 12:7d3c3f7ce928 125 * Sends an AT command
Christopher Haster 12:7d3c3f7ce928 126 *
Christopher Haster 12:7d3c3f7ce928 127 * Sends a formatted command using printf style formatting
Christopher Haster 12:7d3c3f7ce928 128 * @see ::printf
Christopher Haster 12:7d3c3f7ce928 129 *
Christopher Haster 12:7d3c3f7ce928 130 * @param command printf-like format string of command to send which
Christopher Haster 12:7d3c3f7ce928 131 * is appended with the specified delimiter
Christopher Haster 12:7d3c3f7ce928 132 * @param ... all printf-like arguments to insert into command
Christopher Haster 12:7d3c3f7ce928 133 * @return true only if command is successfully sent
Christopher Haster 12:7d3c3f7ce928 134 */
Christopher Haster 12:7d3c3f7ce928 135 bool send(const char *command, ...);
Christopher Haster 12:7d3c3f7ce928 136 bool vsend(const char *command, va_list args);
Christopher Haster 12:7d3c3f7ce928 137
Christopher Haster 12:7d3c3f7ce928 138 /**
Christopher Haster 12:7d3c3f7ce928 139 * Recieve an AT response
Christopher Haster 12:7d3c3f7ce928 140 *
Christopher Haster 12:7d3c3f7ce928 141 * Recieves a formatted response using scanf style formatting
Christopher Haster 12:7d3c3f7ce928 142 * @see ::scanf
Christopher Haster 12:7d3c3f7ce928 143 *
Christopher Haster 12:7d3c3f7ce928 144 * Responses are parsed line at a time using the specified delimiter.
Christopher Haster 12:7d3c3f7ce928 145 * Any recieved data that does not match the response is ignored until
Christopher Haster 12:7d3c3f7ce928 146 * a timeout occurs.
Christopher Haster 12:7d3c3f7ce928 147 *
Christopher Haster 12:7d3c3f7ce928 148 * @param response scanf-like format string of response to expect
Christopher Haster 12:7d3c3f7ce928 149 * @param ... all scanf-like arguments to extract from response
Christopher Haster 12:7d3c3f7ce928 150 * @return true only if response is successfully matched
Christopher Haster 12:7d3c3f7ce928 151 */
Christopher Haster 12:7d3c3f7ce928 152 bool recv(const char *response, ...);
Christopher Haster 12:7d3c3f7ce928 153 bool vrecv(const char *response, va_list args);
Christopher Haster 12:7d3c3f7ce928 154
Christopher Haster 12:7d3c3f7ce928 155 /**
Christopher Haster 12:7d3c3f7ce928 156 * Write a single byte to the underlying stream
Christopher Haster 12:7d3c3f7ce928 157 *
Christopher Haster 12:7d3c3f7ce928 158 * @param c The byte to write
Christopher Haster 12:7d3c3f7ce928 159 * @return The byte that was written or -1 during a timeout
Christopher Haster 12:7d3c3f7ce928 160 */
Christopher Haster 12:7d3c3f7ce928 161 int putc(char c);
Christopher Haster 12:7d3c3f7ce928 162
Christopher Haster 12:7d3c3f7ce928 163 /**
Christopher Haster 12:7d3c3f7ce928 164 * Get a single byte from the underlying stream
Christopher Haster 12:7d3c3f7ce928 165 *
Christopher Haster 12:7d3c3f7ce928 166 * @return The byte that was read or -1 during a timeout
Christopher Haster 12:7d3c3f7ce928 167 */
Christopher Haster 12:7d3c3f7ce928 168 int getc();
Christopher Haster 12:7d3c3f7ce928 169
Christopher Haster 12:7d3c3f7ce928 170 /**
Christopher Haster 12:7d3c3f7ce928 171 * Write an array of bytes to the underlying stream
Christopher Haster 12:7d3c3f7ce928 172 *
Christopher Haster 12:7d3c3f7ce928 173 * @param data the array of bytes to write
Christopher Haster 12:7d3c3f7ce928 174 * @param size number of bytes to write
Christopher Haster 12:7d3c3f7ce928 175 * @return number of bytes written or -1 on failure
Christopher Haster 12:7d3c3f7ce928 176 */
Christopher Haster 12:7d3c3f7ce928 177 int write(const char *data, int size);
Christopher Haster 12:7d3c3f7ce928 178
Christopher Haster 12:7d3c3f7ce928 179 /**
Christopher Haster 12:7d3c3f7ce928 180 * Read an array of bytes from the underlying stream
Christopher Haster 12:7d3c3f7ce928 181 *
Christopher Haster 12:7d3c3f7ce928 182 * @param data the destination for the read bytes
Christopher Haster 12:7d3c3f7ce928 183 * @param size number of bytes to read
Christopher Haster 12:7d3c3f7ce928 184 * @return number of bytes read or -1 on failure
Christopher Haster 12:7d3c3f7ce928 185 */
Christopher Haster 12:7d3c3f7ce928 186 int read(char *data, int size);
Christopher Haster 12:7d3c3f7ce928 187
Christopher Haster 12:7d3c3f7ce928 188 /**
Christopher Haster 12:7d3c3f7ce928 189 * Direct printf to underlying stream
Christopher Haster 12:7d3c3f7ce928 190 * @see ::printf
Christopher Haster 12:7d3c3f7ce928 191 *
Christopher Haster 12:7d3c3f7ce928 192 * @param format format string to pass to printf
Christopher Haster 12:7d3c3f7ce928 193 * @param ... arguments to printf
Christopher Haster 12:7d3c3f7ce928 194 * @return number of bytes written or -1 on failure
Christopher Haster 12:7d3c3f7ce928 195 */
Christopher Haster 12:7d3c3f7ce928 196 int printf(const char *format, ...);
Christopher Haster 12:7d3c3f7ce928 197 int vprintf(const char *format, va_list args);
Christopher Haster 12:7d3c3f7ce928 198
Christopher Haster 12:7d3c3f7ce928 199 /**
Christopher Haster 12:7d3c3f7ce928 200 * Direct scanf on underlying stream
Christopher Haster 12:7d3c3f7ce928 201 * @see ::scanf
Christopher Haster 12:7d3c3f7ce928 202 *
Christopher Haster 12:7d3c3f7ce928 203 * @param format format string to pass to scanf
Christopher Haster 12:7d3c3f7ce928 204 * @param ... arguments to scanf
Christopher Haster 12:7d3c3f7ce928 205 * @return number of bytes read or -1 on failure
Christopher Haster 12:7d3c3f7ce928 206 */
Christopher Haster 12:7d3c3f7ce928 207 int scanf(const char *format, ...);
Christopher Haster 12:7d3c3f7ce928 208 int vscanf(const char *format, va_list args);
Christopher Haster 12:7d3c3f7ce928 209
Christopher Haster 12:7d3c3f7ce928 210 /**
Christopher Haster 12:7d3c3f7ce928 211 * Flushes the underlying stream
Christopher Haster 12:7d3c3f7ce928 212 */
Christopher Haster 12:7d3c3f7ce928 213 void flush();
Christopher Haster 12:7d3c3f7ce928 214 };
Christopher Haster 12:7d3c3f7ce928 215