Added support for the WNC M14A2A Cellular LTE Data Module.

Dependencies:   WNC14A2AInterface

Easy Connect

Easily add all supported connectivity methods to your mbed OS project

This project is derived from https://developer.mbed.org/teams/sandbox/code/simple-mbed-client-example/file/dd6231df71bb/easy-connect.lib. It give user the ability to switch between connectivity methods and includes support for the WNC14A2A Data Module. The `NetworkInterface` API makes this easy, but you still need a mechanism for the user to select the connection method, The selection is made by modifying the `mbed_app.json` file and using `easy_connect()` from your application.

Specifying connectivity method

To add support for the WNC14A2A, add the following to your ``mbed_app.json`` file:

mbed_app.json

{
    "config": {
        "network-interface":{
            "help": "options are ETHERNET,WIFI_ESP8266,WIFI_ODIN,MESH_LOWPAN_ND,MESH_THREAD,WNC14A2A",
            "value": "WNC14A2A"
        }
    },
}

After you choose `WNC14A2A` you'll also need to indicate if you want debug output or not by Enabling (true) or Disabling (false) WNC_DEBUG.

If WNC_DEBUG is enabled, there are 3 different levels of debug output (selected via bit settings). These debug levels are set using the following values:

ValueDescription
1Basic WNC driver debug output
2Comprehensive WNC driver debug output
4Network Layer debug output

You can have any combination of these three bit values for a total value of 0 – 7.

WNC Debug Settings

    "config": {
        "WNC_DEBUG": {
            "value": false
        },
        "WNC_DEBUG_SETTING": {
            "value": 4
        },
    }

Using Easy Connect from your application

Easy Connect has just one function which will either return a `NetworkInterface`-pointer or `NULL`:

Sample Code

#include "easy-connect.h"

int main(int, char**) {
    NetworkInterface* network = easy_connect(true); /* has 1 argument, enable_logging (pass in true to log to serial port) */
    if (!network) {
        printf("Connecting to the network failed... See serial output.\r\n");
        return 1;
    }
 
    // Rest of your program
}

Tested on

  • K64F with Ethernet.
  • AT&T Cellular IoT Starter Kit with WNC M14A2A Cellular Data Module

The WNCInterface class currently supports the following version(s):

  • MPSS: M14A2A_v11.50.164451 APSS: M14A2A_v11.53.164451

License

This library is released under the Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License and may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Committer:
group-Avnet
Date:
Wed Apr 19 01:08:11 2017 +0000
Revision:
0:478cfd88041f
Initial commit

Who changed what in which revision?

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