RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
Parent:
0:38ceb79fef03
2019-03-13

Who changed what in which revision?

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