Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

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