Parser for AT commands and similar protocols

Dependencies:   BufferedSerial

Committer:
geky
Date:
Mon Jul 20 18:23:54 2015 +0000
Revision:
7:d1b193880af1
Parent:
6:51f1171b5ebc
Child:
8:91515b168c70
Modified response parsing to try every character instead of waiting for newlines. This means the ATParser can now handle trailing binary data in AT commands.

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 */
geky 0:c741e144517c 20
geky 0:c741e144517c 21 #include "mbed.h"
geky 5:26bc9255b751 22 #include <cstdarg>
geky 1:66a14afe650a 23
geky 1:66a14afe650a 24 #include "BufferedSerial.h"
geky 0:c741e144517c 25
geky 0:c741e144517c 26
geky 0:c741e144517c 27 /**
geky 0:c741e144517c 28 * The ATParser class wraps information about the serial in use
geky 0:c741e144517c 29 */
geky 0:c741e144517c 30 class ATParser {
geky 0:c741e144517c 31 private:
geky 0:c741e144517c 32 // Serial information
geky 1:66a14afe650a 33 BufferedSerial *_serial;
geky 0:c741e144517c 34 int _buffer_size;
geky 0:c741e144517c 35 char *_buffer;
geky 0:c741e144517c 36 int _timeout;
geky 0:c741e144517c 37
geky 2:4d68f546861c 38 // Parsing information
geky 2:4d68f546861c 39 const char *_delimiter;
geky 7:d1b193880af1 40 int _delim_size;
geky 0:c741e144517c 41
geky 0:c741e144517c 42 public:
geky 0:c741e144517c 43 /**
geky 0:c741e144517c 44 * Constructor
geky 0:c741e144517c 45 *
geky 0:c741e144517c 46 * @param serial serial interface to use for AT commands
geky 1:66a14afe650a 47 * @param buffer_size size of internal buffer for transaction
geky 0:c741e144517c 48 * @param timeout timeout of the connection
geky 2:4d68f546861c 49 * @param delimiter string of characters to use as line delimiters
geky 0:c741e144517c 50 */
geky 5:26bc9255b751 51 ATParser(BufferedSerial *serial, int buffer_size = 256, int timeout = 8000,
geky 2:4d68f546861c 52 const char *delimiter = "\r\n") :
geky 0:c741e144517c 53 _serial(serial),
geky 3:32915b9467d2 54 _buffer_size(buffer_size) {
geky 0:c741e144517c 55 _buffer = new char[buffer_size];
geky 3:32915b9467d2 56 setTimeout(timeout);
geky 3:32915b9467d2 57 setDelimiter(delimiter);
geky 0:c741e144517c 58 }
geky 0:c741e144517c 59
geky 0:c741e144517c 60 /**
geky 0:c741e144517c 61 * Destructor
geky 0:c741e144517c 62 */
geky 0:c741e144517c 63 ~ATParser() {
geky 0:c741e144517c 64 delete [] _buffer;
geky 0:c741e144517c 65 }
geky 0:c741e144517c 66
geky 0:c741e144517c 67 /**
geky 0:c741e144517c 68 * Allows timeout to be changed between commands
geky 0:c741e144517c 69 *
geky 0:c741e144517c 70 * @param timeout timeout of the connection
geky 0:c741e144517c 71 */
geky 0:c741e144517c 72 void setTimeout(int timeout) {
geky 0:c741e144517c 73 _timeout = timeout;
geky 0:c741e144517c 74 }
geky 2:4d68f546861c 75
geky 2:4d68f546861c 76 /**
geky 2:4d68f546861c 77 * Sets string of characters to use as line delimiters
geky 2:4d68f546861c 78 *
geky 2:4d68f546861c 79 * @param delimiter string of characters to use as line delimiters
geky 2:4d68f546861c 80 */
geky 2:4d68f546861c 81 void setDelimiter(const char *delimiter) {
geky 2:4d68f546861c 82 _delimiter = delimiter;
geky 3:32915b9467d2 83 _delim_size = strlen(delimiter);
geky 2:4d68f546861c 84 }
geky 5:26bc9255b751 85
geky 5:26bc9255b751 86 /**
geky 5:26bc9255b751 87 * Sends an AT command
geky 5:26bc9255b751 88 *
geky 5:26bc9255b751 89 * Sends a formatted command using printf style formatting
geky 5:26bc9255b751 90 * @see printf
geky 5:26bc9255b751 91 *
geky 5:26bc9255b751 92 * @param command printf-like format string of command to send which
geky 5:26bc9255b751 93 * is appended with the specified delimiter
geky 5:26bc9255b751 94 * @param ... all printf-like arguments to insert into command
geky 5:26bc9255b751 95 * @return true only if command is successfully sent
geky 5:26bc9255b751 96 */
geky 5:26bc9255b751 97 bool send(const char *command, ...);
geky 5:26bc9255b751 98 bool vsend(const char *command, va_list args);
geky 5:26bc9255b751 99
geky 5:26bc9255b751 100 /**
geky 5:26bc9255b751 101 * Recieve an AT response
geky 5:26bc9255b751 102 *
geky 5:26bc9255b751 103 * Recieves a formatted response using scanf style formatting
geky 5:26bc9255b751 104 * @see scanf
geky 5:26bc9255b751 105 *
geky 5:26bc9255b751 106 * Responses are parsed line at a time using the specified delimiter.
geky 5:26bc9255b751 107 * Any recieved data that does not match the response is ignored until
geky 5:26bc9255b751 108 * a timeout occurs.
geky 5:26bc9255b751 109 *
geky 5:26bc9255b751 110 * @param response scanf-like format string of response to expect
geky 5:26bc9255b751 111 * @param ... all scanf-like arguments to extract from response
geky 5:26bc9255b751 112 * @return true only if response is successfully matched
geky 5:26bc9255b751 113 */
geky 5:26bc9255b751 114 bool recv(const char *response, ...);
geky 5:26bc9255b751 115 bool vrecv(const char *response, va_list args);
geky 0:c741e144517c 116
geky 0:c741e144517c 117 /**
geky 2:4d68f546861c 118 * Issue AT commands
geky 2:4d68f546861c 119 *
geky 5:26bc9255b751 120 * Issues formatted commands and parses formatted responses.
geky 5:26bc9255b751 121 * A command call is identical to a send call followed by a recv call.
geky 5:26bc9255b751 122 * @see send, recv
geky 1:66a14afe650a 123 *
geky 1:66a14afe650a 124 * Here are some examples:
geky 1:66a14afe650a 125 * @code
geky 1:66a14afe650a 126 * at.command("AT", "OK");
geky 1:66a14afe650a 127 * at.command("AT+CWMODE=%d", "OK", 3);
geky 2:4d68f546861c 128 * at.command("AT+CWMODE?", "+CWMODE:%d\r\nOK", &result);
geky 1:66a14afe650a 129 * @endcode
geky 0:c741e144517c 130 *
geky 0:c741e144517c 131 * @param command printf-like format string of command to send
geky 5:26bc9255b751 132 * @param response scanf-like format string of response to expect
geky 0:c741e144517c 133 * @param ... all printf-like arguments to insert into command followed by
geky 5:26bc9255b751 134 * all scanf-like arguments to extract from response
geky 1:66a14afe650a 135 * @return true only if response is successfully matched
geky 0:c741e144517c 136 */
geky 0:c741e144517c 137 bool command(const char *command, const char *response, ...);
geky 5:26bc9255b751 138 bool vcommand(const char *command, const char *response, va_list args);
geky 4:38acbd6f9d9e 139
geky 4:38acbd6f9d9e 140 /**
geky 5:26bc9255b751 141 * Write a single byte to the underlying stream
geky 5:26bc9255b751 142 *
geky 5:26bc9255b751 143 * @param c The byte to write
geky 5:26bc9255b751 144 * @return The byte that was written or -1 during a timeout
geky 5:26bc9255b751 145 */
geky 4:38acbd6f9d9e 146 int putc(char c);
geky 4:38acbd6f9d9e 147
geky 4:38acbd6f9d9e 148 /**
geky 5:26bc9255b751 149 * Get a single byte from the underlying stream
geky 5:26bc9255b751 150 *
geky 5:26bc9255b751 151 * @return The byte that was read or -1 during a timeout
geky 5:26bc9255b751 152 */
geky 4:38acbd6f9d9e 153 int getc();
geky 4:38acbd6f9d9e 154
geky 6:51f1171b5ebc 155 /**
geky 6:51f1171b5ebc 156 * Write an array of bytes to the underlying stream
geky 6:51f1171b5ebc 157 *
geky 6:51f1171b5ebc 158 * @param data the array of bytes to write
geky 6:51f1171b5ebc 159 * @param size number of bytes to write
geky 6:51f1171b5ebc 160 * @return number of bytes written
geky 6:51f1171b5ebc 161 */
geky 6:51f1171b5ebc 162 int write(const char *data, int size);
geky 6:51f1171b5ebc 163
geky 6:51f1171b5ebc 164 /**
geky 6:51f1171b5ebc 165 * Read an array of bytes from the underlying stream
geky 6:51f1171b5ebc 166 *
geky 6:51f1171b5ebc 167 * @param data the destination for the read bytes
geky 6:51f1171b5ebc 168 * @param size number of bytes to read
geky 6:51f1171b5ebc 169 * @return number of bytes read
geky 6:51f1171b5ebc 170 */
geky 6:51f1171b5ebc 171 int read(char *data, int size);
geky 6:51f1171b5ebc 172
geky 4:38acbd6f9d9e 173 /**
geky 5:26bc9255b751 174 * Flushes the underlying stream
geky 5:26bc9255b751 175 */
geky 4:38acbd6f9d9e 176 void flush();
geky 0:c741e144517c 177 };
geky 1:66a14afe650a 178