Parser for AT commands and similar protocols

Dependencies:   BufferedSerial

Committer:
sam_grove
Date:
Sun Jul 26 21:53:28 2015 +0000
Revision:
10:553f9ffaf657
Parent:
9:9bcb87c27208
Child:
11:fd406d4c4227
Small changes

Who changed what in which revision?

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