Parser for AT commands and similar protocols
ATParser.h@12:7d3c3f7ce928, 2016-02-18 (annotated)
- Committer:
- Christopher Haster
- Date:
- Thu Feb 18 15:59:15 2016 -0600
- Revision:
- 12:7d3c3f7ce928
- Parent:
- 11:fd406d4c4227
Removed carriage returns
Who changed what in which revision?
User | Revision | Line number | New 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 |