Parser for AT commands and similar protocols

Dependencies:   BufferedSerial

Committer:
ohlaaa
Date:
Mon Mar 23 07:50:03 2020 +0000
Revision:
17:2a5804e2b440
Parent:
12:7d3c3f7ce928
123

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
Christopher Haster 12:7d3c3f7ce928 53 const char *_delimiter;
Christopher Haster 12:7d3c3f7ce928 54 int _delim_size;
Christopher Haster 12:7d3c3f7ce928 55 bool dbg_on;
Christopher Haster 12:7d3c3f7ce928 56
Christopher Haster 12:7d3c3f7ce928 57 public:
Christopher Haster 12:7d3c3f7ce928 58 /**
Christopher Haster 12:7d3c3f7ce928 59 * Constructor
Christopher Haster 12:7d3c3f7ce928 60 *
Christopher Haster 12:7d3c3f7ce928 61 * @param serial serial interface to use for AT commands
Christopher Haster 12:7d3c3f7ce928 62 * @param buffer_size size of internal buffer for transaction
Christopher Haster 12:7d3c3f7ce928 63 * @param timeout timeout of the connection
Christopher Haster 12:7d3c3f7ce928 64 * @param delimiter string of characters to use as line delimiters
Christopher Haster 12:7d3c3f7ce928 65 */
Christopher Haster 12:7d3c3f7ce928 66 ATParser(BufferedSerial &serial, const char *delimiter = "\r\n", int buffer_size = 256, int timeout = 8000, bool debug = false) :
Christopher Haster 12:7d3c3f7ce928 67 _serial(&serial),
Christopher Haster 12:7d3c3f7ce928 68 _buffer_size(buffer_size) {
Christopher Haster 12:7d3c3f7ce928 69 _buffer = new char[buffer_size];
Christopher Haster 12:7d3c3f7ce928 70 setTimeout(timeout);
Christopher Haster 12:7d3c3f7ce928 71 setDelimiter(delimiter);
Christopher Haster 12:7d3c3f7ce928 72 debugOn(debug);
Christopher Haster 12:7d3c3f7ce928 73 }
Christopher Haster 12:7d3c3f7ce928 74
Christopher Haster 12:7d3c3f7ce928 75 /**
Christopher Haster 12:7d3c3f7ce928 76 * Destructor
Christopher Haster 12:7d3c3f7ce928 77 */
Christopher Haster 12:7d3c3f7ce928 78 ~ATParser() {
Christopher Haster 12:7d3c3f7ce928 79 delete [] _buffer;
Christopher Haster 12:7d3c3f7ce928 80 }
Christopher Haster 12:7d3c3f7ce928 81
Christopher Haster 12:7d3c3f7ce928 82 /**
Christopher Haster 12:7d3c3f7ce928 83 * Allows timeout to be changed between commands
Christopher Haster 12:7d3c3f7ce928 84 *
Christopher Haster 12:7d3c3f7ce928 85 * @param timeout timeout of the connection
Christopher Haster 12:7d3c3f7ce928 86 */
Christopher Haster 12:7d3c3f7ce928 87 void setTimeout(int timeout) {
Christopher Haster 12:7d3c3f7ce928 88 _timeout = timeout;
Christopher Haster 12:7d3c3f7ce928 89 }
Christopher Haster 12:7d3c3f7ce928 90
Christopher Haster 12:7d3c3f7ce928 91 /**
Christopher Haster 12:7d3c3f7ce928 92 * Sets string of characters to use as line delimiters
Christopher Haster 12:7d3c3f7ce928 93 *
Christopher Haster 12:7d3c3f7ce928 94 * @param delimiter string of characters to use as line delimiters
Christopher Haster 12:7d3c3f7ce928 95 */
Christopher Haster 12:7d3c3f7ce928 96 void setDelimiter(const char *delimiter) {
Christopher Haster 12:7d3c3f7ce928 97 _delimiter = delimiter;
Christopher Haster 12:7d3c3f7ce928 98 _delim_size = strlen(delimiter);
Christopher Haster 12:7d3c3f7ce928 99 }
Christopher Haster 12:7d3c3f7ce928 100
Christopher Haster 12:7d3c3f7ce928 101 /**
Christopher Haster 12:7d3c3f7ce928 102 * Allows echo to be on or off
Christopher Haster 12:7d3c3f7ce928 103 *
Christopher Haster 12:7d3c3f7ce928 104 * @param echo 1 for echo and 0 turns it off
Christopher Haster 12:7d3c3f7ce928 105 */
Christopher Haster 12:7d3c3f7ce928 106 void debugOn(uint8_t on) {
Christopher Haster 12:7d3c3f7ce928 107 dbg_on = (on) ? 1 : 0;
Christopher Haster 12:7d3c3f7ce928 108 }
Christopher Haster 12:7d3c3f7ce928 109
Christopher Haster 12:7d3c3f7ce928 110 /**
Christopher Haster 12:7d3c3f7ce928 111 * Sends an AT command
Christopher Haster 12:7d3c3f7ce928 112 *
Christopher Haster 12:7d3c3f7ce928 113 * Sends a formatted command using printf style formatting
Christopher Haster 12:7d3c3f7ce928 114 * @see ::printf
Christopher Haster 12:7d3c3f7ce928 115 *
Christopher Haster 12:7d3c3f7ce928 116 * @param command printf-like format string of command to send which
Christopher Haster 12:7d3c3f7ce928 117 * is appended with the specified delimiter
Christopher Haster 12:7d3c3f7ce928 118 * @param ... all printf-like arguments to insert into command
Christopher Haster 12:7d3c3f7ce928 119 * @return true only if command is successfully sent
Christopher Haster 12:7d3c3f7ce928 120 */
Christopher Haster 12:7d3c3f7ce928 121 bool send(const char *command, ...);
Christopher Haster 12:7d3c3f7ce928 122 bool vsend(const char *command, va_list args);
Christopher Haster 12:7d3c3f7ce928 123
Christopher Haster 12:7d3c3f7ce928 124 /**
Christopher Haster 12:7d3c3f7ce928 125 * Recieve an AT response
Christopher Haster 12:7d3c3f7ce928 126 *
Christopher Haster 12:7d3c3f7ce928 127 * Recieves a formatted response using scanf style formatting
Christopher Haster 12:7d3c3f7ce928 128 * @see ::scanf
Christopher Haster 12:7d3c3f7ce928 129 *
Christopher Haster 12:7d3c3f7ce928 130 * Responses are parsed line at a time using the specified delimiter.
Christopher Haster 12:7d3c3f7ce928 131 * Any recieved data that does not match the response is ignored until
Christopher Haster 12:7d3c3f7ce928 132 * a timeout occurs.
Christopher Haster 12:7d3c3f7ce928 133 *
Christopher Haster 12:7d3c3f7ce928 134 * @param response scanf-like format string of response to expect
Christopher Haster 12:7d3c3f7ce928 135 * @param ... all scanf-like arguments to extract from response
Christopher Haster 12:7d3c3f7ce928 136 * @return true only if response is successfully matched
Christopher Haster 12:7d3c3f7ce928 137 */
Christopher Haster 12:7d3c3f7ce928 138 bool recv(const char *response, ...);
Christopher Haster 12:7d3c3f7ce928 139 bool vrecv(const char *response, va_list args);
Christopher Haster 12:7d3c3f7ce928 140
Christopher Haster 12:7d3c3f7ce928 141 /**
Christopher Haster 12:7d3c3f7ce928 142 * Write a single byte to the underlying stream
Christopher Haster 12:7d3c3f7ce928 143 *
Christopher Haster 12:7d3c3f7ce928 144 * @param c The byte to write
Christopher Haster 12:7d3c3f7ce928 145 * @return The byte that was written or -1 during a timeout
Christopher Haster 12:7d3c3f7ce928 146 */
Christopher Haster 12:7d3c3f7ce928 147 int putc(char c);
Christopher Haster 12:7d3c3f7ce928 148
Christopher Haster 12:7d3c3f7ce928 149 /**
Christopher Haster 12:7d3c3f7ce928 150 * Get a single byte from the underlying stream
Christopher Haster 12:7d3c3f7ce928 151 *
Christopher Haster 12:7d3c3f7ce928 152 * @return The byte that was read or -1 during a timeout
Christopher Haster 12:7d3c3f7ce928 153 */
Christopher Haster 12:7d3c3f7ce928 154 int getc();
Christopher Haster 12:7d3c3f7ce928 155
Christopher Haster 12:7d3c3f7ce928 156 /**
Christopher Haster 12:7d3c3f7ce928 157 * Write an array of bytes to the underlying stream
Christopher Haster 12:7d3c3f7ce928 158 *
Christopher Haster 12:7d3c3f7ce928 159 * @param data the array of bytes to write
Christopher Haster 12:7d3c3f7ce928 160 * @param size number of bytes to write
Christopher Haster 12:7d3c3f7ce928 161 * @return number of bytes written or -1 on failure
Christopher Haster 12:7d3c3f7ce928 162 */
Christopher Haster 12:7d3c3f7ce928 163 int write(const char *data, int size);
Christopher Haster 12:7d3c3f7ce928 164
Christopher Haster 12:7d3c3f7ce928 165 /**
Christopher Haster 12:7d3c3f7ce928 166 * Read an array of bytes from the underlying stream
Christopher Haster 12:7d3c3f7ce928 167 *
Christopher Haster 12:7d3c3f7ce928 168 * @param data the destination for the read bytes
Christopher Haster 12:7d3c3f7ce928 169 * @param size number of bytes to read
Christopher Haster 12:7d3c3f7ce928 170 * @return number of bytes read or -1 on failure
Christopher Haster 12:7d3c3f7ce928 171 */
Christopher Haster 12:7d3c3f7ce928 172 int read(char *data, int size);
Christopher Haster 12:7d3c3f7ce928 173
Christopher Haster 12:7d3c3f7ce928 174 /**
Christopher Haster 12:7d3c3f7ce928 175 * Direct printf to underlying stream
Christopher Haster 12:7d3c3f7ce928 176 * @see ::printf
Christopher Haster 12:7d3c3f7ce928 177 *
Christopher Haster 12:7d3c3f7ce928 178 * @param format format string to pass to printf
Christopher Haster 12:7d3c3f7ce928 179 * @param ... arguments to printf
Christopher Haster 12:7d3c3f7ce928 180 * @return number of bytes written or -1 on failure
Christopher Haster 12:7d3c3f7ce928 181 */
Christopher Haster 12:7d3c3f7ce928 182 int printf(const char *format, ...);
Christopher Haster 12:7d3c3f7ce928 183 int vprintf(const char *format, va_list args);
Christopher Haster 12:7d3c3f7ce928 184
Christopher Haster 12:7d3c3f7ce928 185 /**
Christopher Haster 12:7d3c3f7ce928 186 * Direct scanf on underlying stream
Christopher Haster 12:7d3c3f7ce928 187 * @see ::scanf
Christopher Haster 12:7d3c3f7ce928 188 *
Christopher Haster 12:7d3c3f7ce928 189 * @param format format string to pass to scanf
Christopher Haster 12:7d3c3f7ce928 190 * @param ... arguments to scanf
Christopher Haster 12:7d3c3f7ce928 191 * @return number of bytes read or -1 on failure
Christopher Haster 12:7d3c3f7ce928 192 */
Christopher Haster 12:7d3c3f7ce928 193 int scanf(const char *format, ...);
Christopher Haster 12:7d3c3f7ce928 194 int vscanf(const char *format, va_list args);
Christopher Haster 12:7d3c3f7ce928 195
Christopher Haster 12:7d3c3f7ce928 196 /**
Christopher Haster 12:7d3c3f7ce928 197 * Flushes the underlying stream
Christopher Haster 12:7d3c3f7ce928 198 */
Christopher Haster 12:7d3c3f7ce928 199 void flush();
Christopher Haster 12:7d3c3f7ce928 200 };
Christopher Haster 12:7d3c3f7ce928 201