Fork for workshops

Committer:
JimCarver
Date:
Fri Oct 12 21:22:49 2018 +0000
Revision:
0:6b753f761943
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JimCarver 0:6b753f761943 1 /* Copyright (c) 2015 ARM Limited
JimCarver 0:6b753f761943 2 *
JimCarver 0:6b753f761943 3 * Licensed under the Apache License, Version 2.0 (the "License");
JimCarver 0:6b753f761943 4 * you may not use this file except in compliance with the License.
JimCarver 0:6b753f761943 5 * You may obtain a copy of the License at
JimCarver 0:6b753f761943 6 *
JimCarver 0:6b753f761943 7 * http://www.apache.org/licenses/LICENSE-2.0
JimCarver 0:6b753f761943 8 *
JimCarver 0:6b753f761943 9 * Unless required by applicable law or agreed to in writing, software
JimCarver 0:6b753f761943 10 * distributed under the License is distributed on an "AS IS" BASIS,
JimCarver 0:6b753f761943 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
JimCarver 0:6b753f761943 12 * See the License for the specific language governing permissions and
JimCarver 0:6b753f761943 13 * limitations under the License.
JimCarver 0:6b753f761943 14 *
JimCarver 0:6b753f761943 15 * @section DESCRIPTION
JimCarver 0:6b753f761943 16 *
JimCarver 0:6b753f761943 17 * Parser for the AT command syntax
JimCarver 0:6b753f761943 18 *
JimCarver 0:6b753f761943 19 */
JimCarver 0:6b753f761943 20
JimCarver 0:6b753f761943 21 #include "ATParser.h"
JimCarver 0:6b753f761943 22 #include "mbed_debug.h"
JimCarver 0:6b753f761943 23
JimCarver 0:6b753f761943 24 #ifdef LF
JimCarver 0:6b753f761943 25 #undef LF
JimCarver 0:6b753f761943 26 #define LF 10
JimCarver 0:6b753f761943 27 #else
JimCarver 0:6b753f761943 28 #define LF 10
JimCarver 0:6b753f761943 29 #endif
JimCarver 0:6b753f761943 30
JimCarver 0:6b753f761943 31 #ifdef CR
JimCarver 0:6b753f761943 32 #undef CR
JimCarver 0:6b753f761943 33 #define CR 13
JimCarver 0:6b753f761943 34 #else
JimCarver 0:6b753f761943 35 #define CR 13
JimCarver 0:6b753f761943 36 #endif
JimCarver 0:6b753f761943 37 #define MIN(a,b) (((a)<(b))?(a):(b))
JimCarver 0:6b753f761943 38
JimCarver 0:6b753f761943 39 // activate / de-activate debug
JimCarver 0:6b753f761943 40 #define dbg_on 0
JimCarver 0:6b753f761943 41 #define AT_DATA_PRINT 0
JimCarver 0:6b753f761943 42 #define AT_COMMAND_PRINT 0
JimCarver 0:6b753f761943 43 #define AT_HEXA_DATA 0
JimCarver 0:6b753f761943 44
JimCarver 0:6b753f761943 45 ATParser::ATParser(BufferedSpi &serial_spi, const char *delimiter, int buffer_size, int timeout) :
JimCarver 0:6b753f761943 46 _serial_spi(&serial_spi),
JimCarver 0:6b753f761943 47 _buffer_size(buffer_size), _in_prev(0), _oobs(NULL)
JimCarver 0:6b753f761943 48 {
JimCarver 0:6b753f761943 49 _buffer = new char[buffer_size];
JimCarver 0:6b753f761943 50 setTimeout(timeout);
JimCarver 0:6b753f761943 51 setDelimiter(delimiter);
JimCarver 0:6b753f761943 52 }
JimCarver 0:6b753f761943 53
JimCarver 0:6b753f761943 54
JimCarver 0:6b753f761943 55 // getc/putc handling with timeouts
JimCarver 0:6b753f761943 56 int ATParser::putc(char c)
JimCarver 0:6b753f761943 57 {
JimCarver 0:6b753f761943 58 return _serial_spi->putc(c);
JimCarver 0:6b753f761943 59 }
JimCarver 0:6b753f761943 60
JimCarver 0:6b753f761943 61 int ATParser::getc()
JimCarver 0:6b753f761943 62 {
JimCarver 0:6b753f761943 63 return _serial_spi->getc();
JimCarver 0:6b753f761943 64 }
JimCarver 0:6b753f761943 65
JimCarver 0:6b753f761943 66 void ATParser::flush()
JimCarver 0:6b753f761943 67 {
JimCarver 0:6b753f761943 68 _bufferMutex.lock();
JimCarver 0:6b753f761943 69 while (_serial_spi->readable()) {
JimCarver 0:6b753f761943 70 _serial_spi->getc();
JimCarver 0:6b753f761943 71 }
JimCarver 0:6b753f761943 72 _bufferMutex.unlock();
JimCarver 0:6b753f761943 73 }
JimCarver 0:6b753f761943 74
JimCarver 0:6b753f761943 75 // read/write handling with timeouts
JimCarver 0:6b753f761943 76 int ATParser::write(const char *data, int size_of_data, int size_in_buff)
JimCarver 0:6b753f761943 77 {
JimCarver 0:6b753f761943 78 int i = 0;
JimCarver 0:6b753f761943 79 _bufferMutex.lock();
JimCarver 0:6b753f761943 80 debug_if(dbg_on, "ATParser write: %d BYTES\r\n", size_of_data);
JimCarver 0:6b753f761943 81 debug_if(AT_DATA_PRINT, "ATParser write: (ASCII) ", size_of_data);
JimCarver 0:6b753f761943 82 for (; i < size_of_data; i++) {
JimCarver 0:6b753f761943 83 debug_if(AT_DATA_PRINT, "%c", data[i]);
JimCarver 0:6b753f761943 84 if (putc(data[i]) < 0) {
JimCarver 0:6b753f761943 85 debug_if(AT_DATA_PRINT, "\r\n");
JimCarver 0:6b753f761943 86 _bufferMutex.unlock();
JimCarver 0:6b753f761943 87 return -1;
JimCarver 0:6b753f761943 88 }
JimCarver 0:6b753f761943 89 }
JimCarver 0:6b753f761943 90 debug_if(AT_DATA_PRINT, "\r\n");
JimCarver 0:6b753f761943 91
JimCarver 0:6b753f761943 92 _serial_spi->buffsend(size_of_data + size_in_buff);
JimCarver 0:6b753f761943 93 _bufferMutex.unlock();
JimCarver 0:6b753f761943 94
JimCarver 0:6b753f761943 95 return (size_of_data + size_in_buff);
JimCarver 0:6b753f761943 96 }
JimCarver 0:6b753f761943 97
JimCarver 0:6b753f761943 98 int ATParser::read(char *data)
JimCarver 0:6b753f761943 99 {
JimCarver 0:6b753f761943 100 int readsize;
JimCarver 0:6b753f761943 101 int i = 0;
JimCarver 0:6b753f761943 102
JimCarver 0:6b753f761943 103 _bufferMutex.lock();
JimCarver 0:6b753f761943 104
JimCarver 0:6b753f761943 105 //this->flush();
JimCarver 0:6b753f761943 106 if (!_serial_spi->readable()) {
JimCarver 0:6b753f761943 107 readsize = _serial_spi->read();
JimCarver 0:6b753f761943 108 } else {
JimCarver 0:6b753f761943 109 debug_if(dbg_on, "Pending data when reading from WIFI\r\n");
JimCarver 0:6b753f761943 110 return -1;
JimCarver 0:6b753f761943 111 }
JimCarver 0:6b753f761943 112
JimCarver 0:6b753f761943 113 debug_if(dbg_on, "ATParser read: %d data avail in SPI\r\n", readsize);
JimCarver 0:6b753f761943 114
JimCarver 0:6b753f761943 115 if (readsize < 0) {
JimCarver 0:6b753f761943 116 _bufferMutex.unlock();
JimCarver 0:6b753f761943 117 return -1;
JimCarver 0:6b753f761943 118 }
JimCarver 0:6b753f761943 119
JimCarver 0:6b753f761943 120 for (i = 0 ; i < readsize; i++) {
JimCarver 0:6b753f761943 121 int c = getc();
JimCarver 0:6b753f761943 122 if (c < 0) {
JimCarver 0:6b753f761943 123 _bufferMutex.unlock();
JimCarver 0:6b753f761943 124 return -1;
JimCarver 0:6b753f761943 125 }
JimCarver 0:6b753f761943 126 data[i] = c;
JimCarver 0:6b753f761943 127 }
JimCarver 0:6b753f761943 128
JimCarver 0:6b753f761943 129 #if AT_HEXA_DATA
JimCarver 0:6b753f761943 130 debug_if(AT_DATA_PRINT, "ATParser read: (HEXA) ");
JimCarver 0:6b753f761943 131 for (i = 0; i < readsize; i++) {
JimCarver 0:6b753f761943 132 debug_if(AT_DATA_PRINT, "%2X ", data[i]);
JimCarver 0:6b753f761943 133 if ((i + 1) % 20 == 0) {
JimCarver 0:6b753f761943 134 debug_if(AT_DATA_PRINT, "\r\n");
JimCarver 0:6b753f761943 135 }
JimCarver 0:6b753f761943 136 }
JimCarver 0:6b753f761943 137 debug_if(AT_DATA_PRINT, "\r\n");
JimCarver 0:6b753f761943 138 #endif
JimCarver 0:6b753f761943 139 debug_if(AT_DATA_PRINT, "ATParser read: (ASCII) ");
JimCarver 0:6b753f761943 140 for (i = 0; i < readsize; i++) {
JimCarver 0:6b753f761943 141 debug_if(AT_DATA_PRINT, "%c", data[i]);
JimCarver 0:6b753f761943 142 }
JimCarver 0:6b753f761943 143 debug_if(AT_DATA_PRINT, "\r\n");
JimCarver 0:6b753f761943 144
JimCarver 0:6b753f761943 145 _bufferMutex.unlock();
JimCarver 0:6b753f761943 146
JimCarver 0:6b753f761943 147 return (readsize);
JimCarver 0:6b753f761943 148 }
JimCarver 0:6b753f761943 149
JimCarver 0:6b753f761943 150 // printf/scanf handling
JimCarver 0:6b753f761943 151 int ATParser::vprintf(const char *format, va_list args)
JimCarver 0:6b753f761943 152 {
JimCarver 0:6b753f761943 153 _bufferMutex.lock();
JimCarver 0:6b753f761943 154 if (vsprintf(_buffer, format, args) < 0) {
JimCarver 0:6b753f761943 155 _bufferMutex.unlock();
JimCarver 0:6b753f761943 156 return false;
JimCarver 0:6b753f761943 157 }
JimCarver 0:6b753f761943 158
JimCarver 0:6b753f761943 159 int i = 0;
JimCarver 0:6b753f761943 160 for (; _buffer[i]; i++) {
JimCarver 0:6b753f761943 161 if (putc(_buffer[i]) < 0) {
JimCarver 0:6b753f761943 162 _bufferMutex.unlock();
JimCarver 0:6b753f761943 163 return -1;
JimCarver 0:6b753f761943 164 }
JimCarver 0:6b753f761943 165 }
JimCarver 0:6b753f761943 166 _bufferMutex.unlock();
JimCarver 0:6b753f761943 167
JimCarver 0:6b753f761943 168 return i;
JimCarver 0:6b753f761943 169 }
JimCarver 0:6b753f761943 170
JimCarver 0:6b753f761943 171 int ATParser::vscanf(const char *format, va_list args)
JimCarver 0:6b753f761943 172 {
JimCarver 0:6b753f761943 173 // Since format is const, we need to copy it into our buffer to
JimCarver 0:6b753f761943 174 // add the line's null terminator and clobber value-matches with asterisks.
JimCarver 0:6b753f761943 175 //
JimCarver 0:6b753f761943 176 // We just use the beginning of the buffer to avoid unnecessary allocations.
JimCarver 0:6b753f761943 177 int i = 0;
JimCarver 0:6b753f761943 178 int offset = 0;
JimCarver 0:6b753f761943 179
JimCarver 0:6b753f761943 180 _bufferMutex.lock();
JimCarver 0:6b753f761943 181
JimCarver 0:6b753f761943 182 while (format[i]) {
JimCarver 0:6b753f761943 183 if (format[i] == '%' && format[i + 1] != '%' && format[i + 1] != '*') {
JimCarver 0:6b753f761943 184 _buffer[offset++] = '%';
JimCarver 0:6b753f761943 185 _buffer[offset++] = '*';
JimCarver 0:6b753f761943 186 i++;
JimCarver 0:6b753f761943 187 } else {
JimCarver 0:6b753f761943 188 _buffer[offset++] = format[i++];
JimCarver 0:6b753f761943 189 }
JimCarver 0:6b753f761943 190 }
JimCarver 0:6b753f761943 191
JimCarver 0:6b753f761943 192 // Scanf has very poor support for catching errors
JimCarver 0:6b753f761943 193 // fortunately, we can abuse the %n specifier to determine
JimCarver 0:6b753f761943 194 // if the entire string was matched.
JimCarver 0:6b753f761943 195 _buffer[offset++] = '%';
JimCarver 0:6b753f761943 196 _buffer[offset++] = 'n';
JimCarver 0:6b753f761943 197 _buffer[offset++] = 0;
JimCarver 0:6b753f761943 198
JimCarver 0:6b753f761943 199 // To workaround scanf's lack of error reporting, we actually
JimCarver 0:6b753f761943 200 // make two passes. One checks the validity with the modified
JimCarver 0:6b753f761943 201 // format string that only stores the matched characters (%n).
JimCarver 0:6b753f761943 202 // The other reads in the actual matched values.
JimCarver 0:6b753f761943 203 //
JimCarver 0:6b753f761943 204 // We keep trying the match until we succeed or some other error
JimCarver 0:6b753f761943 205 // derails us.
JimCarver 0:6b753f761943 206 int j = 0;
JimCarver 0:6b753f761943 207
JimCarver 0:6b753f761943 208 while (true) {
JimCarver 0:6b753f761943 209 // Ran out of space
JimCarver 0:6b753f761943 210 if (j + 1 >= _buffer_size - offset) {
JimCarver 0:6b753f761943 211 _bufferMutex.unlock();
JimCarver 0:6b753f761943 212 return false;
JimCarver 0:6b753f761943 213 }
JimCarver 0:6b753f761943 214 // Recieve next character
JimCarver 0:6b753f761943 215 int c = getc();
JimCarver 0:6b753f761943 216 if (c < 0) {
JimCarver 0:6b753f761943 217 _bufferMutex.unlock();
JimCarver 0:6b753f761943 218 return -1;
JimCarver 0:6b753f761943 219 }
JimCarver 0:6b753f761943 220 _buffer[offset + j++] = c;
JimCarver 0:6b753f761943 221 _buffer[offset + j] = 0;
JimCarver 0:6b753f761943 222
JimCarver 0:6b753f761943 223 // Check for match
JimCarver 0:6b753f761943 224 int count = -1;
JimCarver 0:6b753f761943 225 sscanf(_buffer + offset, _buffer, &count);
JimCarver 0:6b753f761943 226
JimCarver 0:6b753f761943 227 // We only succeed if all characters in the response are matched
JimCarver 0:6b753f761943 228 if (count == j) {
JimCarver 0:6b753f761943 229 // Store the found results
JimCarver 0:6b753f761943 230 vsscanf(_buffer + offset, format, args);
JimCarver 0:6b753f761943 231 _bufferMutex.unlock();
JimCarver 0:6b753f761943 232 return j;
JimCarver 0:6b753f761943 233 }
JimCarver 0:6b753f761943 234 }
JimCarver 0:6b753f761943 235 }
JimCarver 0:6b753f761943 236
JimCarver 0:6b753f761943 237
JimCarver 0:6b753f761943 238 // Command parsing with line handling
JimCarver 0:6b753f761943 239 bool ATParser::vsend(const char *command, va_list args)
JimCarver 0:6b753f761943 240 {
JimCarver 0:6b753f761943 241 int i = 0, j = 0;
JimCarver 0:6b753f761943 242 _bufferMutex.lock();
JimCarver 0:6b753f761943 243 // Create and send command
JimCarver 0:6b753f761943 244 if (vsprintf(_buffer, command, args) < 0) {
JimCarver 0:6b753f761943 245 _bufferMutex.unlock();
JimCarver 0:6b753f761943 246 return false;
JimCarver 0:6b753f761943 247 }
JimCarver 0:6b753f761943 248 /* get buffer length */
JimCarver 0:6b753f761943 249 for (i = 0; _buffer[i]; i++) {
JimCarver 0:6b753f761943 250 }
JimCarver 0:6b753f761943 251
JimCarver 0:6b753f761943 252 for (j = 0; _delimiter[j]; j++) {
JimCarver 0:6b753f761943 253 _buffer[i + j] = _delimiter[j];
JimCarver 0:6b753f761943 254 }
JimCarver 0:6b753f761943 255 _buffer[i + j] = 0; // only to get a clean debug log
JimCarver 0:6b753f761943 256
JimCarver 0:6b753f761943 257 bool ret = !(_serial_spi->buffwrite(_buffer, i + j) < 0);
JimCarver 0:6b753f761943 258
JimCarver 0:6b753f761943 259 debug_if(AT_COMMAND_PRINT, "AT> %s\n", _buffer);
JimCarver 0:6b753f761943 260 _bufferMutex.unlock();
JimCarver 0:6b753f761943 261 return ret;
JimCarver 0:6b753f761943 262 }
JimCarver 0:6b753f761943 263
JimCarver 0:6b753f761943 264 bool ATParser::vrecv(const char *response, va_list args)
JimCarver 0:6b753f761943 265 {
JimCarver 0:6b753f761943 266 _bufferMutex.lock();
JimCarver 0:6b753f761943 267
JimCarver 0:6b753f761943 268 if (!_serial_spi->readable()) {
JimCarver 0:6b753f761943 269 // debug_if(dbg_on, "NO DATA, read again\r\n");
JimCarver 0:6b753f761943 270 if (_serial_spi->read() < 0) {
JimCarver 0:6b753f761943 271 return false;
JimCarver 0:6b753f761943 272 }
JimCarver 0:6b753f761943 273 }
JimCarver 0:6b753f761943 274 // else {
JimCarver 0:6b753f761943 275 // debug_if(dbg_on, "Pending data\r\n");
JimCarver 0:6b753f761943 276 // }
JimCarver 0:6b753f761943 277
JimCarver 0:6b753f761943 278 restart:
JimCarver 0:6b753f761943 279 _aborted = false;
JimCarver 0:6b753f761943 280 // Iterate through each line in the expected response
JimCarver 0:6b753f761943 281 while (response[0]) {
JimCarver 0:6b753f761943 282 // Since response is const, we need to copy it into our buffer to
JimCarver 0:6b753f761943 283 // add the line's null terminator and clobber value-matches with asterisks.
JimCarver 0:6b753f761943 284 //
JimCarver 0:6b753f761943 285 // We just use the beginning of the buffer to avoid unnecessary allocations.
JimCarver 0:6b753f761943 286 int i = 0;
JimCarver 0:6b753f761943 287 int offset = 0;
JimCarver 0:6b753f761943 288 bool whole_line_wanted = false;
JimCarver 0:6b753f761943 289
JimCarver 0:6b753f761943 290 while (response[i]) {
JimCarver 0:6b753f761943 291 if (response[i] == '%' && response[i + 1] != '%' && response[i + 1] != '*') {
JimCarver 0:6b753f761943 292 _buffer[offset++] = '%';
JimCarver 0:6b753f761943 293 _buffer[offset++] = '*';
JimCarver 0:6b753f761943 294 i++;
JimCarver 0:6b753f761943 295 } else {
JimCarver 0:6b753f761943 296 _buffer[offset++] = response[i++];
JimCarver 0:6b753f761943 297 // Find linebreaks, taking care not to be fooled if they're in a %[^\n] conversion specification
JimCarver 0:6b753f761943 298 if (response[i - 1] == '\n' && !(i >= 3 && response[i - 3] == '[' && response[i - 2] == '^')) {
JimCarver 0:6b753f761943 299 whole_line_wanted = true;
JimCarver 0:6b753f761943 300 break;
JimCarver 0:6b753f761943 301 }
JimCarver 0:6b753f761943 302 }
JimCarver 0:6b753f761943 303 }
JimCarver 0:6b753f761943 304
JimCarver 0:6b753f761943 305 // Scanf has very poor support for catching errors
JimCarver 0:6b753f761943 306 // fortunately, we can abuse the %n specifier to determine
JimCarver 0:6b753f761943 307 // if the entire string was matched.
JimCarver 0:6b753f761943 308 _buffer[offset++] = '%';
JimCarver 0:6b753f761943 309 _buffer[offset++] = 'n';
JimCarver 0:6b753f761943 310 _buffer[offset++] = 0;
JimCarver 0:6b753f761943 311
JimCarver 0:6b753f761943 312 // debug_if(dbg_on, "ATParser vrecv: AT? ====%s====\n", _buffer);
JimCarver 0:6b753f761943 313 // To workaround scanf's lack of error reporting, we actually
JimCarver 0:6b753f761943 314 // make two passes. One checks the validity with the modified
JimCarver 0:6b753f761943 315 // format string that only stores the matched characters (%n).
JimCarver 0:6b753f761943 316 // The other reads in the actual matched values.
JimCarver 0:6b753f761943 317 //
JimCarver 0:6b753f761943 318 // We keep trying the match until we succeed or some other error
JimCarver 0:6b753f761943 319 // derails us.
JimCarver 0:6b753f761943 320 int j = 0;
JimCarver 0:6b753f761943 321
JimCarver 0:6b753f761943 322 while (true) {
JimCarver 0:6b753f761943 323 // Recieve next character
JimCarver 0:6b753f761943 324 int c = getc();
JimCarver 0:6b753f761943 325 if (c < 0) {
JimCarver 0:6b753f761943 326 debug_if(dbg_on, "AT(Timeout)\n");
JimCarver 0:6b753f761943 327 _bufferMutex.unlock();
JimCarver 0:6b753f761943 328 return false;
JimCarver 0:6b753f761943 329 }
JimCarver 0:6b753f761943 330
JimCarver 0:6b753f761943 331 // debug_if(AT_DATA_PRINT, "%2X ", c);
JimCarver 0:6b753f761943 332
JimCarver 0:6b753f761943 333 _buffer[offset + j++] = c;
JimCarver 0:6b753f761943 334 _buffer[offset + j] = 0;
JimCarver 0:6b753f761943 335
JimCarver 0:6b753f761943 336 // Check for oob data
JimCarver 0:6b753f761943 337 for (struct oob *oob = _oobs; oob; oob = oob->next) {
JimCarver 0:6b753f761943 338 if ((unsigned)j == oob->len && memcmp(
JimCarver 0:6b753f761943 339 oob->prefix, _buffer + offset, oob->len) == 0) {
JimCarver 0:6b753f761943 340 debug_if(dbg_on, "AT! %s\n", oob->prefix);
JimCarver 0:6b753f761943 341 oob->cb();
JimCarver 0:6b753f761943 342
JimCarver 0:6b753f761943 343 if (_aborted) {
JimCarver 0:6b753f761943 344 debug_if(dbg_on, "AT(Aborted)\n");
JimCarver 0:6b753f761943 345 _bufferMutex.unlock();
JimCarver 0:6b753f761943 346 return false;
JimCarver 0:6b753f761943 347 }
JimCarver 0:6b753f761943 348 // oob may have corrupted non-reentrant buffer,
JimCarver 0:6b753f761943 349 // so we need to set it up again
JimCarver 0:6b753f761943 350 goto restart;
JimCarver 0:6b753f761943 351 }
JimCarver 0:6b753f761943 352 }
JimCarver 0:6b753f761943 353
JimCarver 0:6b753f761943 354 // Check for match
JimCarver 0:6b753f761943 355 int count = -1;
JimCarver 0:6b753f761943 356 if (whole_line_wanted && c != '\n') {
JimCarver 0:6b753f761943 357 // Don't attempt scanning until we get delimiter if they included it in format
JimCarver 0:6b753f761943 358 // This allows recv("Foo: %s\n") to work, and not match with just the first character of a string
JimCarver 0:6b753f761943 359 // (scanf does not itself match whitespace in its format string, so \n is not significant to it)
JimCarver 0:6b753f761943 360 } else {
JimCarver 0:6b753f761943 361 sscanf(_buffer + offset, _buffer, &count);
JimCarver 0:6b753f761943 362 }
JimCarver 0:6b753f761943 363
JimCarver 0:6b753f761943 364 // We only succeed if all characters in the response are matched
JimCarver 0:6b753f761943 365 if (count == j) {
JimCarver 0:6b753f761943 366 debug_if(AT_COMMAND_PRINT, "AT= ====%s====\n", _buffer + offset);
JimCarver 0:6b753f761943 367 // Reuse the front end of the buffer
JimCarver 0:6b753f761943 368 memcpy(_buffer, response, i);
JimCarver 0:6b753f761943 369 _buffer[i] = 0;
JimCarver 0:6b753f761943 370
JimCarver 0:6b753f761943 371 // Store the found results
JimCarver 0:6b753f761943 372 vsscanf(_buffer + offset, _buffer, args);
JimCarver 0:6b753f761943 373
JimCarver 0:6b753f761943 374 // Jump to next line and continue parsing
JimCarver 0:6b753f761943 375 response += i;
JimCarver 0:6b753f761943 376 break;
JimCarver 0:6b753f761943 377 }
JimCarver 0:6b753f761943 378
JimCarver 0:6b753f761943 379 // Clear the buffer when we hit a newline or ran out of space
JimCarver 0:6b753f761943 380 // running out of space usually means we ran into binary data
JimCarver 0:6b753f761943 381 if ((c == '\n')) {
JimCarver 0:6b753f761943 382 // debug_if(dbg_on, "New line AT<<< %s", _buffer+offset);
JimCarver 0:6b753f761943 383 j = 0;
JimCarver 0:6b753f761943 384 }
JimCarver 0:6b753f761943 385 if ((j + 1 >= (_buffer_size - offset))) {
JimCarver 0:6b753f761943 386
JimCarver 0:6b753f761943 387 debug_if(dbg_on, "Out of space AT<<< %s, j=%d", _buffer + offset, j);
JimCarver 0:6b753f761943 388 j = 0;
JimCarver 0:6b753f761943 389 }
JimCarver 0:6b753f761943 390 }
JimCarver 0:6b753f761943 391 }
JimCarver 0:6b753f761943 392
JimCarver 0:6b753f761943 393 _bufferMutex.unlock();
JimCarver 0:6b753f761943 394
JimCarver 0:6b753f761943 395 return true;
JimCarver 0:6b753f761943 396 }
JimCarver 0:6b753f761943 397
JimCarver 0:6b753f761943 398
JimCarver 0:6b753f761943 399 // Mapping to vararg functions
JimCarver 0:6b753f761943 400 int ATParser::printf(const char *format, ...)
JimCarver 0:6b753f761943 401 {
JimCarver 0:6b753f761943 402 va_list args;
JimCarver 0:6b753f761943 403 va_start(args, format);
JimCarver 0:6b753f761943 404 int res = vprintf(format, args);
JimCarver 0:6b753f761943 405 va_end(args);
JimCarver 0:6b753f761943 406 return res;
JimCarver 0:6b753f761943 407 }
JimCarver 0:6b753f761943 408
JimCarver 0:6b753f761943 409 int ATParser::scanf(const char *format, ...)
JimCarver 0:6b753f761943 410 {
JimCarver 0:6b753f761943 411 va_list args;
JimCarver 0:6b753f761943 412 va_start(args, format);
JimCarver 0:6b753f761943 413 int res = vscanf(format, args);
JimCarver 0:6b753f761943 414 va_end(args);
JimCarver 0:6b753f761943 415 return res;
JimCarver 0:6b753f761943 416 }
JimCarver 0:6b753f761943 417
JimCarver 0:6b753f761943 418 bool ATParser::send(const char *command, ...)
JimCarver 0:6b753f761943 419 {
JimCarver 0:6b753f761943 420 va_list args;
JimCarver 0:6b753f761943 421 va_start(args, command);
JimCarver 0:6b753f761943 422 bool res = vsend(command, args);
JimCarver 0:6b753f761943 423 va_end(args);
JimCarver 0:6b753f761943 424 return res;
JimCarver 0:6b753f761943 425 }
JimCarver 0:6b753f761943 426
JimCarver 0:6b753f761943 427 bool ATParser::recv(const char *response, ...)
JimCarver 0:6b753f761943 428 {
JimCarver 0:6b753f761943 429 va_list args;
JimCarver 0:6b753f761943 430 va_start(args, response);
JimCarver 0:6b753f761943 431 bool res = vrecv(response, args);
JimCarver 0:6b753f761943 432 va_end(args);
JimCarver 0:6b753f761943 433 return res;
JimCarver 0:6b753f761943 434 }
JimCarver 0:6b753f761943 435
JimCarver 0:6b753f761943 436
JimCarver 0:6b753f761943 437 // oob registration
JimCarver 0:6b753f761943 438 void ATParser::oob(const char *prefix, Callback<void()> cb)
JimCarver 0:6b753f761943 439 {
JimCarver 0:6b753f761943 440 struct oob *oob = new struct oob;
JimCarver 0:6b753f761943 441 oob->len = strlen(prefix);
JimCarver 0:6b753f761943 442 oob->prefix = prefix;
JimCarver 0:6b753f761943 443 oob->cb = cb;
JimCarver 0:6b753f761943 444 oob->next = _oobs;
JimCarver 0:6b753f761943 445 _oobs = oob;
JimCarver 0:6b753f761943 446 }
JimCarver 0:6b753f761943 447
JimCarver 0:6b753f761943 448 void ATParser::abort()
JimCarver 0:6b753f761943 449 {
JimCarver 0:6b753f761943 450 _aborted = true;
JimCarver 0:6b753f761943 451 }
JimCarver 0:6b753f761943 452
JimCarver 0:6b753f761943 453
JimCarver 0:6b753f761943 454