mbed library sources. Supersedes mbed-src.

Dependents:   BREAK_SENSOR_LED

Fork of mbed-dev by mbed official

Committer:
Anythingconnected
Date:
Mon Dec 18 10:14:27 2017 +0000
Revision:
180:d79f997829d6
Parent:
176:447f873cad2f
Getting byte by byte read to work

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 167:e84263d55307 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 167:e84263d55307 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 167:e84263d55307 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 167:e84263d55307 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 167:e84263d55307 158 if (j+1 >= _buffer_size - offset) {
AnnaBridge 167:e84263d55307 159 return false;
AnnaBridge 167:e84263d55307 160 }
AnnaBridge 167:e84263d55307 161 // Recieve 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 167:e84263d55307 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 167:e84263d55307 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 167:e84263d55307 213 while (response[0]) {
AnnaBridge 167:e84263d55307 214 // Since response is const, we need to copy it into our buffer to
AnnaBridge 167:e84263d55307 215 // add the line's null terminator and clobber value-matches with asterisks.
AnnaBridge 167:e84263d55307 216 //
AnnaBridge 167:e84263d55307 217 // We just use the beginning of the buffer to avoid unnecessary allocations.
AnnaBridge 167:e84263d55307 218 int i = 0;
AnnaBridge 167:e84263d55307 219 int offset = 0;
AnnaBridge 167:e84263d55307 220 bool whole_line_wanted = false;
AnnaBridge 167:e84263d55307 221
AnnaBridge 167:e84263d55307 222 while (response[i]) {
AnnaBridge 167:e84263d55307 223 if (response[i] == '%' && response[i+1] != '%' && response[i+1] != '*') {
AnnaBridge 167:e84263d55307 224 _buffer[offset++] = '%';
AnnaBridge 167:e84263d55307 225 _buffer[offset++] = '*';
AnnaBridge 167:e84263d55307 226 i++;
AnnaBridge 167:e84263d55307 227 } else {
AnnaBridge 167:e84263d55307 228 _buffer[offset++] = response[i++];
AnnaBridge 167:e84263d55307 229 // Find linebreaks, taking care not to be fooled if they're in a %[^\n] conversion specification
AnnaBridge 167:e84263d55307 230 if (response[i - 1] == '\n' && !(i >= 3 && response[i-3] == '[' && response[i-2] == '^')) {
AnnaBridge 167:e84263d55307 231 whole_line_wanted = true;
AnnaBridge 167:e84263d55307 232 break;
AnnaBridge 167:e84263d55307 233 }
AnnaBridge 167:e84263d55307 234 }
AnnaBridge 167:e84263d55307 235 }
AnnaBridge 167:e84263d55307 236
AnnaBridge 167:e84263d55307 237 // Scanf has very poor support for catching errors
AnnaBridge 167:e84263d55307 238 // fortunately, we can abuse the %n specifier to determine
AnnaBridge 167:e84263d55307 239 // if the entire string was matched.
AnnaBridge 167:e84263d55307 240 _buffer[offset++] = '%';
AnnaBridge 167:e84263d55307 241 _buffer[offset++] = 'n';
AnnaBridge 167:e84263d55307 242 _buffer[offset++] = 0;
AnnaBridge 167:e84263d55307 243
AnnaBridge 167:e84263d55307 244 debug_if(_dbg_on, "AT? %s\n", _buffer);
AnnaBridge 167:e84263d55307 245 // To workaround scanf's lack of error reporting, we actually
AnnaBridge 167:e84263d55307 246 // make two passes. One checks the validity with the modified
AnnaBridge 167:e84263d55307 247 // format string that only stores the matched characters (%n).
AnnaBridge 167:e84263d55307 248 // The other reads in the actual matched values.
AnnaBridge 167:e84263d55307 249 //
AnnaBridge 167:e84263d55307 250 // We keep trying the match until we succeed or some other error
AnnaBridge 167:e84263d55307 251 // derails us.
AnnaBridge 167:e84263d55307 252 int j = 0;
AnnaBridge 167:e84263d55307 253
AnnaBridge 167:e84263d55307 254 while (true) {
AnnaBridge 167:e84263d55307 255 // Receive next character
AnnaBridge 167:e84263d55307 256 int c = getc();
AnnaBridge 167:e84263d55307 257 if (c < 0) {
AnnaBridge 167:e84263d55307 258 debug_if(_dbg_on, "AT(Timeout)\n");
AnnaBridge 167:e84263d55307 259 return false;
AnnaBridge 167:e84263d55307 260 }
AnnaBridge 167:e84263d55307 261 // Simplify newlines (borrowed from retarget.cpp)
AnnaBridge 167:e84263d55307 262 if ((c == CR && _in_prev != LF) ||
AnnaBridge 167:e84263d55307 263 (c == LF && _in_prev != CR)) {
AnnaBridge 167:e84263d55307 264 _in_prev = c;
AnnaBridge 167:e84263d55307 265 c = '\n';
AnnaBridge 167:e84263d55307 266 } else if ((c == CR && _in_prev == LF) ||
AnnaBridge 167:e84263d55307 267 (c == LF && _in_prev == CR)) {
AnnaBridge 167:e84263d55307 268 _in_prev = c;
AnnaBridge 167:e84263d55307 269 // onto next character
AnnaBridge 167:e84263d55307 270 continue;
AnnaBridge 167:e84263d55307 271 } else {
AnnaBridge 167:e84263d55307 272 _in_prev = c;
AnnaBridge 167:e84263d55307 273 }
AnnaBridge 167:e84263d55307 274 _buffer[offset + j++] = c;
AnnaBridge 167:e84263d55307 275 _buffer[offset + j] = 0;
AnnaBridge 167:e84263d55307 276
AnnaBridge 167:e84263d55307 277 // Check for oob data
AnnaBridge 167:e84263d55307 278 for (struct oob *oob = _oobs; oob; oob = oob->next) {
AnnaBridge 167:e84263d55307 279 if ((unsigned)j == oob->len && memcmp(
AnnaBridge 167:e84263d55307 280 oob->prefix, _buffer+offset, oob->len) == 0) {
AnnaBridge 167:e84263d55307 281 debug_if(_dbg_on, "AT! %s\n", oob->prefix);
AnnaBridge 167:e84263d55307 282 oob->cb();
AnnaBridge 167:e84263d55307 283
AnnaBridge 167:e84263d55307 284 if (_aborted) {
AnnaBridge 167:e84263d55307 285 debug_if(_dbg_on, "AT(Aborted)\n");
AnnaBridge 167:e84263d55307 286 return false;
AnnaBridge 167:e84263d55307 287 }
AnnaBridge 167:e84263d55307 288 // oob may have corrupted non-reentrant buffer,
AnnaBridge 167:e84263d55307 289 // so we need to set it up again
AnnaBridge 167:e84263d55307 290 goto restart;
AnnaBridge 167:e84263d55307 291 }
AnnaBridge 167:e84263d55307 292 }
AnnaBridge 167:e84263d55307 293
AnnaBridge 167:e84263d55307 294 // Check for match
AnnaBridge 167:e84263d55307 295 int count = -1;
AnnaBridge 167:e84263d55307 296 if (whole_line_wanted && c != '\n') {
AnnaBridge 167:e84263d55307 297 // Don't attempt scanning until we get delimiter if they included it in format
AnnaBridge 167:e84263d55307 298 // This allows recv("Foo: %s\n") to work, and not match with just the first character of a string
AnnaBridge 167:e84263d55307 299 // (scanf does not itself match whitespace in its format string, so \n is not significant to it)
AnnaBridge 167:e84263d55307 300 } else {
AnnaBridge 167:e84263d55307 301 sscanf(_buffer+offset, _buffer, &count);
AnnaBridge 167:e84263d55307 302 }
AnnaBridge 167:e84263d55307 303
AnnaBridge 167:e84263d55307 304 // We only succeed if all characters in the response are matched
AnnaBridge 167:e84263d55307 305 if (count == j) {
AnnaBridge 167:e84263d55307 306 debug_if(_dbg_on, "AT= %s\n", _buffer+offset);
AnnaBridge 167:e84263d55307 307 // Reuse the front end of the buffer
AnnaBridge 167:e84263d55307 308 memcpy(_buffer, response, i);
AnnaBridge 167:e84263d55307 309 _buffer[i] = 0;
AnnaBridge 167:e84263d55307 310
AnnaBridge 167:e84263d55307 311 // Store the found results
AnnaBridge 167:e84263d55307 312 vsscanf(_buffer+offset, _buffer, args);
AnnaBridge 167:e84263d55307 313
AnnaBridge 167:e84263d55307 314 // Jump to next line and continue parsing
AnnaBridge 167:e84263d55307 315 response += i;
AnnaBridge 167:e84263d55307 316 break;
AnnaBridge 167:e84263d55307 317 }
AnnaBridge 167:e84263d55307 318
AnnaBridge 167:e84263d55307 319 // Clear the buffer when we hit a newline or ran out of space
AnnaBridge 167:e84263d55307 320 // running out of space usually means we ran into binary data
AnnaBridge 167:e84263d55307 321 if (c == '\n' || j+1 >= _buffer_size - offset) {
AnnaBridge 167:e84263d55307 322 debug_if(_dbg_on, "AT< %s", _buffer+offset);
AnnaBridge 167:e84263d55307 323 j = 0;
AnnaBridge 167:e84263d55307 324 }
AnnaBridge 167:e84263d55307 325 }
AnnaBridge 167:e84263d55307 326 }
AnnaBridge 167:e84263d55307 327
AnnaBridge 167:e84263d55307 328 return true;
AnnaBridge 167:e84263d55307 329 }
AnnaBridge 167:e84263d55307 330
AnnaBridge 167:e84263d55307 331 // Mapping to vararg functions
AnnaBridge 167:e84263d55307 332 int ATCmdParser::printf(const char *format, ...)
AnnaBridge 167:e84263d55307 333 {
AnnaBridge 167:e84263d55307 334 va_list args;
AnnaBridge 167:e84263d55307 335 va_start(args, format);
AnnaBridge 167:e84263d55307 336 int res = vprintf(format, args);
AnnaBridge 167:e84263d55307 337 va_end(args);
AnnaBridge 167:e84263d55307 338 return res;
AnnaBridge 167:e84263d55307 339 }
AnnaBridge 167:e84263d55307 340
AnnaBridge 167:e84263d55307 341 int ATCmdParser::scanf(const char *format, ...)
AnnaBridge 167:e84263d55307 342 {
AnnaBridge 167:e84263d55307 343 va_list args;
AnnaBridge 167:e84263d55307 344 va_start(args, format);
AnnaBridge 167:e84263d55307 345 int res = vscanf(format, args);
AnnaBridge 167:e84263d55307 346 va_end(args);
AnnaBridge 167:e84263d55307 347 return res;
AnnaBridge 167:e84263d55307 348 }
AnnaBridge 167:e84263d55307 349
AnnaBridge 167:e84263d55307 350 bool ATCmdParser::send(const char *command, ...)
AnnaBridge 167:e84263d55307 351 {
AnnaBridge 167:e84263d55307 352 va_list args;
AnnaBridge 167:e84263d55307 353 va_start(args, command);
AnnaBridge 167:e84263d55307 354 bool res = vsend(command, args);
AnnaBridge 167:e84263d55307 355 va_end(args);
AnnaBridge 167:e84263d55307 356 return res;
AnnaBridge 167:e84263d55307 357 }
AnnaBridge 167:e84263d55307 358
AnnaBridge 167:e84263d55307 359 bool ATCmdParser::recv(const char *response, ...)
AnnaBridge 167:e84263d55307 360 {
AnnaBridge 167:e84263d55307 361 va_list args;
AnnaBridge 167:e84263d55307 362 va_start(args, response);
AnnaBridge 167:e84263d55307 363 bool res = vrecv(response, args);
AnnaBridge 167:e84263d55307 364 va_end(args);
AnnaBridge 167:e84263d55307 365 return res;
AnnaBridge 167:e84263d55307 366 }
AnnaBridge 167:e84263d55307 367
AnnaBridge 167:e84263d55307 368 // oob registration
AnnaBridge 167:e84263d55307 369 void ATCmdParser::oob(const char *prefix, Callback<void()> cb)
AnnaBridge 167:e84263d55307 370 {
AnnaBridge 167:e84263d55307 371 struct oob *oob = new struct oob;
AnnaBridge 167:e84263d55307 372 oob->len = strlen(prefix);
AnnaBridge 167:e84263d55307 373 oob->prefix = prefix;
AnnaBridge 167:e84263d55307 374 oob->cb = cb;
AnnaBridge 167:e84263d55307 375 oob->next = _oobs;
AnnaBridge 167:e84263d55307 376 _oobs = oob;
AnnaBridge 167:e84263d55307 377 }
AnnaBridge 167:e84263d55307 378
AnnaBridge 167:e84263d55307 379 void ATCmdParser::abort()
AnnaBridge 167:e84263d55307 380 {
AnnaBridge 167:e84263d55307 381 _aborted = true;
AnnaBridge 167:e84263d55307 382 }
AnnaBridge 176:447f873cad2f 383
AnnaBridge 176:447f873cad2f 384 bool ATCmdParser::process_oob()
AnnaBridge 176:447f873cad2f 385 {
AnnaBridge 176:447f873cad2f 386 if (!_fh->readable()) {
AnnaBridge 176:447f873cad2f 387 return false;
AnnaBridge 176:447f873cad2f 388 }
AnnaBridge 176:447f873cad2f 389
AnnaBridge 176:447f873cad2f 390 int i = 0;
AnnaBridge 176:447f873cad2f 391 while (true) {
AnnaBridge 176:447f873cad2f 392 // Receive next character
AnnaBridge 176:447f873cad2f 393 int c = getc();
AnnaBridge 176:447f873cad2f 394 if (c < 0) {
AnnaBridge 176:447f873cad2f 395 return false;
AnnaBridge 176:447f873cad2f 396 }
AnnaBridge 176:447f873cad2f 397 _buffer[i++] = c;
AnnaBridge 176:447f873cad2f 398 _buffer[i] = 0;
AnnaBridge 176:447f873cad2f 399
AnnaBridge 176:447f873cad2f 400 // Check for oob data
AnnaBridge 176:447f873cad2f 401 struct oob *oob = _oobs;
AnnaBridge 176:447f873cad2f 402 while (oob) {
AnnaBridge 176:447f873cad2f 403 if (i == (int)oob->len && memcmp(
AnnaBridge 176:447f873cad2f 404 oob->prefix, _buffer, oob->len) == 0) {
AnnaBridge 176:447f873cad2f 405 debug_if(_dbg_on, "AT! %s\r\n", oob->prefix);
AnnaBridge 176:447f873cad2f 406 oob->cb();
AnnaBridge 176:447f873cad2f 407 return true;
AnnaBridge 176:447f873cad2f 408 }
AnnaBridge 176:447f873cad2f 409 oob = oob->next;
AnnaBridge 176:447f873cad2f 410 }
AnnaBridge 176:447f873cad2f 411
AnnaBridge 176:447f873cad2f 412 // Clear the buffer when we hit a newline or ran out of space
AnnaBridge 176:447f873cad2f 413 // running out of space usually means we ran into binary data
AnnaBridge 176:447f873cad2f 414 if (i+1 >= _buffer_size ||
AnnaBridge 176:447f873cad2f 415 strcmp(&_buffer[i-_output_delim_size], _output_delimiter) == 0) {
AnnaBridge 176:447f873cad2f 416
AnnaBridge 176:447f873cad2f 417 debug_if(_dbg_on, "AT< %s", _buffer);
AnnaBridge 176:447f873cad2f 418 i = 0;
AnnaBridge 176:447f873cad2f 419 }
AnnaBridge 176:447f873cad2f 420 }
AnnaBridge 176:447f873cad2f 421 }
AnnaBridge 176:447f873cad2f 422
AnnaBridge 176:447f873cad2f 423