@@ -124,68 +124,6 @@ int ATCmdParser::vprintf(const char *format, std::va_list args)
124
124
return i;
125
125
}
126
126
127
- int ATCmdParser::vscanf (const char *format, std::va_list args)
128
- {
129
- // Since format is const, we need to copy it into our buffer to
130
- // add the line's null terminator and clobber value-matches with asterisks.
131
- //
132
- // We just use the beginning of the buffer to avoid unnecessary allocations.
133
- int i = 0 ;
134
- int offset = 0 ;
135
-
136
- while (format[i]) {
137
- if (format[i] == ' %' && format[i + 1 ] != ' %' && format[i + 1 ] != ' *' ) {
138
- _buffer[offset++] = ' %' ;
139
- _buffer[offset++] = ' *' ;
140
- i++;
141
- } else {
142
- _buffer[offset++] = format[i++];
143
- }
144
- }
145
-
146
- // Scanf has very poor support for catching errors
147
- // fortunately, we can abuse the %n specifier to determine
148
- // if the entire string was matched.
149
- _buffer[offset++] = ' %' ;
150
- _buffer[offset++] = ' n' ;
151
- _buffer[offset++] = 0 ;
152
-
153
- // To workaround scanf's lack of error reporting, we actually
154
- // make two passes. One checks the validity with the modified
155
- // format string that only stores the matched characters (%n).
156
- // The other reads in the actual matched values.
157
- //
158
- // We keep trying the match until we succeed or some other error
159
- // derails us.
160
- int j = 0 ;
161
-
162
- while (true ) {
163
- // Ran out of space
164
- if (j + 1 >= _buffer_size - offset) {
165
- return false ;
166
- }
167
- // Receive next character
168
- int c = getc ();
169
- if (c < 0 ) {
170
- return -1 ;
171
- }
172
- _buffer[offset + j++] = c;
173
- _buffer[offset + j] = 0 ;
174
-
175
- // Check for match
176
- int count = -1 ;
177
- sscanf (_buffer + offset, _buffer, &count);
178
-
179
- // We only succeed if all characters in the response are matched
180
- if (count == j) {
181
- // Store the found results
182
- vsscanf (_buffer + offset, format, args);
183
- return j;
184
- }
185
- }
186
- }
187
-
188
-
189
127
// Command parsing with line handling
190
128
bool ATCmdParser::vsend (const char *command, std::va_list args)
191
129
{
@@ -211,7 +149,7 @@ bool ATCmdParser::vsend(const char *command, std::va_list args)
211
149
return true ;
212
150
}
213
151
214
- bool ATCmdParser::vrecv (const char *response, std::va_list args)
152
+ int ATCmdParser::vrecvscanf (const char *response, std::va_list args, bool multiline )
215
153
{
216
154
restart:
217
155
_aborted = false ;
@@ -259,17 +197,24 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
259
197
int j = 0 ;
260
198
261
199
while (true ) {
200
+ // Ran out of space
201
+ if (j + 1 >= _buffer_size - offset) {
202
+ return -1 ;
203
+ }
204
+
262
205
// If just peeking for OOBs, and at start of line, check
263
206
// readability
264
207
if (!response && j == 0 && !_fh->readable ()) {
265
- return false ;
208
+ return - 1 ;
266
209
}
210
+
267
211
// Receive next character
268
212
int c = getc ();
269
213
if (c < 0 ) {
270
214
debug_if (_dbg_on, " AT(Timeout)\n " );
271
- return false ;
215
+ return - 1 ;
272
216
}
217
+
273
218
// Simplify newlines (borrowed from retarget.cpp)
274
219
if ((c == CR && _in_prev != LF) ||
275
220
(c == LF && _in_prev != CR)) {
@@ -283,24 +228,27 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
283
228
} else {
284
229
_in_prev = c;
285
230
}
231
+
286
232
_buffer[offset + j++] = c;
287
233
_buffer[offset + j] = 0 ;
288
234
289
235
// Check for oob data
290
- for (struct oob *oob = _oobs; oob; oob = oob->next ) {
291
- if ((unsigned )j == oob->len && memcmp (
292
- oob->prefix , _buffer + offset, oob->len ) == 0 ) {
293
- debug_if (_dbg_on, " AT! %s\n " , oob->prefix );
294
- _oob_cb_count++;
295
- oob->cb ();
296
-
297
- if (_aborted) {
298
- debug_if (_dbg_on, " AT(Aborted)\n " );
299
- return false ;
236
+ if (multiline) {
237
+ for (struct oob *oob = _oobs; oob; oob = oob->next ) {
238
+ if ((unsigned )j == oob->len && memcmp (
239
+ oob->prefix , _buffer + offset, oob->len ) == 0 ) {
240
+ debug_if (_dbg_on, " AT! %s\n " , oob->prefix );
241
+ _oob_cb_count++;
242
+ oob->cb ();
243
+
244
+ if (_aborted) {
245
+ debug_if (_dbg_on, " AT(Aborted)\n " );
246
+ return false ;
247
+ }
248
+ // oob may have corrupted non-reentrant buffer,
249
+ // so we need to set it up again
250
+ goto restart;
300
251
}
301
- // oob may have corrupted non-reentrant buffer,
302
- // so we need to set it up again
303
- goto restart;
304
252
}
305
253
}
306
254
@@ -323,6 +271,10 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
323
271
// Store the found results
324
272
vsscanf (_buffer + offset, _buffer, args);
325
273
274
+ if (!multiline) {
275
+ return j;
276
+ }
277
+
326
278
// Jump to next line and continue parsing
327
279
response += i;
328
280
break ;
@@ -337,7 +289,7 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
337
289
}
338
290
}
339
291
340
- return true ;
292
+ return 1 ;
341
293
}
342
294
343
295
// Mapping to vararg functions
@@ -354,7 +306,7 @@ int ATCmdParser::scanf(const char *format, ...)
354
306
{
355
307
std::va_list args;
356
308
va_start (args, format);
357
- int res = vscanf (format, args);
309
+ int res = vrecvscanf (format, args, false );
358
310
va_end (args);
359
311
return res;
360
312
}
@@ -372,9 +324,9 @@ bool ATCmdParser::recv(const char *response, ...)
372
324
{
373
325
std::va_list args;
374
326
va_start (args, response);
375
- bool res = vrecv (response, args);
327
+ int res = vrecvscanf (response, args, true );
376
328
va_end (args);
377
- return res;
329
+ return ( res > 0 ) ? true : false ;
378
330
}
379
331
380
332
// oob registration
0 commit comments