@@ -124,94 +124,7 @@ 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
- // Command parsing with line handling
190
- bool ATCmdParser::vsend (const char *command, std::va_list args)
191
- {
192
- // Create and send command
193
- if (vsprintf (_buffer, command, args) < 0 ) {
194
- return false ;
195
- }
196
-
197
- for (int i = 0 ; _buffer[i]; i++) {
198
- if (putc (_buffer[i]) < 0 ) {
199
- return false ;
200
- }
201
- }
202
-
203
- // Finish with newline
204
- for (size_t i = 0 ; _output_delimiter[i]; i++) {
205
- if (putc (_output_delimiter[i]) < 0 ) {
206
- return false ;
207
- }
208
- }
209
-
210
- debug_if (_dbg_on, " AT> %s\n " , _buffer);
211
- return true ;
212
- }
213
-
214
- bool ATCmdParser::vrecv (const char *response, std::va_list args)
127
+ int ATCmdParser::vrecvscanf (const char *response, std::va_list args, bool issacnf)
215
128
{
216
129
restart:
217
130
_aborted = false ;
@@ -259,20 +172,27 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
259
172
int j = 0 ;
260
173
261
174
while (true ) {
175
+ // Ran out of space
176
+ if (j + 1 >= _buffer_size - offset) {
177
+ return -1 ;
178
+ }
179
+
262
180
// If just peeking for OOBs, and at start of line, check
263
181
// readability
264
- if (!response && j == 0 && !_fh->readable ()) {
265
- return false ;
182
+ if (!issacnf && ! response && j == 0 && !_fh->readable ()) {
183
+ return - 1 ;
266
184
}
185
+
267
186
// Receive next character
268
187
int c = getc ();
269
188
if (c < 0 ) {
270
189
debug_if (_dbg_on, " AT(Timeout)\n " );
271
- return false ;
190
+ return - 1 ;
272
191
}
192
+
273
193
// Simplify newlines (borrowed from retarget.cpp)
274
194
if ((c == CR && _in_prev != LF) ||
275
- (c == LF && _in_prev != CR)) {
195
+ (c == LF && _in_prev != CR)) {
276
196
_in_prev = c;
277
197
c = ' \n ' ;
278
198
} else if ((c == CR && _in_prev == LF) ||
@@ -283,24 +203,27 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
283
203
} else {
284
204
_in_prev = c;
285
205
}
206
+
286
207
_buffer[offset + j++] = c;
287
208
_buffer[offset + j] = 0 ;
288
209
289
210
// 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 ;
211
+ if (!issacnf) {
212
+ for (struct oob *oob = _oobs; oob; oob = oob->next ) {
213
+ if ((unsigned )j == oob->len && memcmp (
214
+ oob->prefix , _buffer + offset, oob->len ) == 0 ) {
215
+ debug_if (_dbg_on, " AT! %s\n " , oob->prefix );
216
+ _oob_cb_count++;
217
+ oob->cb ();
218
+
219
+ if (_aborted) {
220
+ debug_if (_dbg_on, " AT(Aborted)\n " );
221
+ return false ;
222
+ }
223
+ // oob may have corrupted non-reentrant buffer,
224
+ // so we need to set it up again
225
+ goto restart;
300
226
}
301
- // oob may have corrupted non-reentrant buffer,
302
- // so we need to set it up again
303
- goto restart;
304
227
}
305
228
}
306
229
@@ -323,6 +246,10 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
323
246
// Store the found results
324
247
vsscanf (_buffer + offset, _buffer, args);
325
248
249
+ if (issacnf) {
250
+ return j;
251
+ }
252
+
326
253
// Jump to next line and continue parsing
327
254
response += i;
328
255
break ;
@@ -337,6 +264,31 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
337
264
}
338
265
}
339
266
267
+ return 1 ;
268
+ }
269
+
270
+ // Command parsing with line handling
271
+ bool ATCmdParser::vsend (const char *command, std::va_list args)
272
+ {
273
+ // Create and send command
274
+ if (vsprintf (_buffer, command, args) < 0 ) {
275
+ return false ;
276
+ }
277
+
278
+ for (int i = 0 ; _buffer[i]; i++) {
279
+ if (putc (_buffer[i]) < 0 ) {
280
+ return false ;
281
+ }
282
+ }
283
+
284
+ // Finish with newline
285
+ for (size_t i = 0 ; _output_delimiter[i]; i++) {
286
+ if (putc (_output_delimiter[i]) < 0 ) {
287
+ return false ;
288
+ }
289
+ }
290
+
291
+ debug_if (_dbg_on, " AT> %s\n " , _buffer);
340
292
return true ;
341
293
}
342
294
@@ -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, true );
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, false );
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