EMW3162 driver for NSAPI

Dependents:   HelloEMW3162

Fork of emw3162-driver by Maggie Mei

Committer:
Maggie17
Date:
Thu Apr 06 02:58:04 2017 +0000
Revision:
3:a1d89edf0749
Parent:
0:2d5090e1ceb4
change _esp to _emw

Who changed what in which revision?

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