Opencv 3.1 project on GR-PEACH board

Fork of gr-peach-opencv-project by the do

Committer:
thedo
Date:
Tue Jul 04 06:23:13 2017 +0000
Revision:
170:54ff26da7eb6
Parent:
166:3a9487d57a5c
project opencv 3.1 on GR PEACH board, no use SD card.

Who changed what in which revision?

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