mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Thu Nov 08 11:46:34 2018 +0000
Revision:
188:bcfe06ba3d64
Parent:
187:0387e8f68319
Child:
189:f392fc9709a3
mbed-dev library. Release version 164

Who changed what in which revision?

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