Disco-L475VG-IOT / wifi-ism43362
Committer:
marcel1691
Date:
Wed Oct 03 14:03:01 2018 +0000
Revision:
0:62e55edab701
WiFi ISM43363

Who changed what in which revision?

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