Initial commit

Dependencies:   FastPWM

Committer:
lypinator
Date:
Wed Sep 16 01:11:49 2020 +0000
Revision:
0:bb348c97df44
Added PWM

Who changed what in which revision?

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