Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

Committer:
MACRUM
Date:
Sat Jun 30 01:40:30 2018 +0000
Revision:
0:119624335925
Initial commit

Who changed what in which revision?

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