FreeCalypso > hg > fc-magnetite
comparison src/aci2/aci/ati_prs.c @ 3:93999a60b835
src/aci2, src/condat2: import of g23m/condat source pieces from TCS211
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 26 Sep 2016 00:29:36 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:c41a534f33c6 | 3:93999a60b835 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : GSM-F&D (8411) | |
4 | Modul : ATI | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : AT Command parameter parser | |
18 +----------------------------------------------------------------------------- | |
19 */ | |
20 | |
21 #ifndef ATI_PRS_C | |
22 #define ATI_PRS_C | |
23 | |
24 #include "aci_all.h" | |
25 | |
26 #include <stdarg.h> | |
27 #include <ctype.h> | |
28 | |
29 #include "aci_cmh.h" | |
30 #include "ati_cmd.h" | |
31 #include "aci_cmd.h" | |
32 | |
33 #ifdef OPTION_RELATIVE | |
34 LOCAL ULONG offset; | |
35 #endif | |
36 | |
37 static UBYTE parse_index = 0; | |
38 | |
39 /* | |
40 +--------------------------------------------------------------------+ | |
41 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
42 | STATE : code ROUTINE : parseBin | | |
43 +--------------------------------------------------------------------+ | |
44 | |
45 PURPOSE : parse binary value | |
46 | |
47 */ | |
48 | |
49 GLOBAL char *parseBin (int digits, char *b, SHORT *i) | |
50 { | |
51 int found = 0; | |
52 | |
53 *i = 0; | |
54 while (digits-- AND *b >= '0' AND *b <= '1') | |
55 { | |
56 found++; | |
57 *i *= 2; | |
58 *i += *b - '0'; | |
59 b++; | |
60 } | |
61 | |
62 return ((found) ? b : 0); | |
63 } | |
64 | |
65 | |
66 /* | |
67 +--------------------------------------------------------------------+ | |
68 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
69 | STATE : code ROUTINE : parseHex | | |
70 +--------------------------------------------------------------------+ | |
71 | |
72 PURPOSE : parse hexadecimal value | |
73 | |
74 */ | |
75 | |
76 GLOBAL char *parseHex (int digits, char *b, UBYTE *i) | |
77 { | |
78 int found = 0; | |
79 | |
80 *i = 0; | |
81 while (digits-- AND ((*b >= '0' AND *b <= '9') OR | |
82 (*b >= 'a' AND *b <= 'f') OR | |
83 (*b >= 'A' AND *b <= 'F'))) | |
84 { | |
85 found++; | |
86 *i *= 16; | |
87 if (*b >= '0' AND *b <= '9') | |
88 *i += *b - '0'; | |
89 if (*b >= 'a' AND *b <= 'f') | |
90 *i += *b - 'a' + 10; | |
91 if (*b >= 'A' AND *b <= 'F') | |
92 *i += *b - 'A' + 10; | |
93 b++; | |
94 } | |
95 | |
96 return ((found AND found <= 2) ? b : 0); | |
97 } | |
98 | |
99 /* | |
100 +--------------------------------------------------------------------+ | |
101 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
102 | STATE : code ROUTINE : parseHexToLong | | |
103 +--------------------------------------------------------------------+ | |
104 | |
105 PURPOSE : parse hexadecimal value | |
106 | |
107 */ | |
108 | |
109 GLOBAL char *parseHexToLong (int digits, char *b, LONG *i) | |
110 { | |
111 *i = 0; | |
112 while (digits-- AND ((*b >= '0' AND *b <= '9') OR | |
113 (*b >= 'a' AND *b <= 'f') OR | |
114 (*b >= 'A' AND *b <= 'F'))) | |
115 { | |
116 *i *= 16; | |
117 if (*b >= '0' AND *b <= '9') | |
118 *i += *b - '0'; | |
119 if (*b >= 'a' AND *b <= 'f') | |
120 *i += *b - 'a' + 10; | |
121 if (*b >= 'A' AND *b <= 'F') | |
122 *i += *b - 'A' + 10; | |
123 b++; | |
124 } | |
125 | |
126 return ( digits EQ 0 ? 0 : b ); | |
127 } | |
128 | |
129 /* | |
130 +--------------------------------------------------------------------+ | |
131 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
132 | STATE : code ROUTINE : parseEnum | | |
133 +--------------------------------------------------------------------+ | |
134 | |
135 PURPOSE : parse enum value | |
136 | |
137 */ | |
138 | |
139 GLOBAL char *parseEnum (int digits, char *b, int *i) | |
140 { | |
141 int found = 0; | |
142 | |
143 *i = 0; | |
144 while (digits-- AND *b >= '0' AND *b <= '9') | |
145 { | |
146 found++; | |
147 *i *= 10; | |
148 *i += *b - '0'; | |
149 b++; | |
150 } | |
151 | |
152 return ((found) ? b : 0); | |
153 } | |
154 | |
155 /* | |
156 +--------------------------------------------------------------------+ | |
157 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
158 | STATE : code ROUTINE : parseShort | | |
159 +--------------------------------------------------------------------+ | |
160 | |
161 PURPOSE : parse Short value | |
162 | |
163 */ | |
164 | |
165 GLOBAL char *parseShort (int digits, char *b, SHORT *i) | |
166 { | |
167 int found = 0; | |
168 | |
169 *i = 0; | |
170 while (digits-- AND *b >= '0' AND *b <= '9') | |
171 { | |
172 found++; | |
173 *i *= 10; | |
174 *i += *b - '0'; | |
175 b++; | |
176 } | |
177 | |
178 return ((found) ? b : 0); | |
179 } | |
180 | |
181 | |
182 /* | |
183 +--------------------------------------------------------------------+ | |
184 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
185 | STATE : code ROUTINE : parseStr | | |
186 +--------------------------------------------------------------------+ | |
187 | |
188 PURPOSE : parse string value | |
189 | |
190 */ | |
191 | |
192 GLOBAL char *parseStr (int digits, char *b, char *s) | |
193 { | |
194 int found = 0; | |
195 | |
196 *s = 0; | |
197 if (*b != '"') | |
198 return 0; | |
199 b++; | |
200 while (digits-- AND *b AND *b >= 0x20) | |
201 { | |
202 found++; | |
203 if (*b == '"') | |
204 { | |
205 *s = 0; | |
206 b++; | |
207 break; | |
208 } | |
209 if (*b == '\\') | |
210 { | |
211 b = parseHex(2,b+1,(UBYTE *) s); /* ES!! ZERO ? */ | |
212 if (!b) | |
213 return 0; | |
214 s++; | |
215 } | |
216 else | |
217 *s++ = *b++; | |
218 } | |
219 if(*(b-1) NEQ '"') | |
220 return 0; | |
221 *s = 0; /* zero terminated */ | |
222 | |
223 return ((found) ? b : 0); | |
224 } | |
225 | |
226 /* | |
227 +--------------------------------------------------------------------+ | |
228 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
229 | STATE : code ROUTINE : parseZStr | | |
230 +--------------------------------------------------------------------+ | |
231 | |
232 PURPOSE : parse string value | |
233 | |
234 */ | |
235 | |
236 GLOBAL char *parseZStr (int digits, char *b, char *s) | |
237 { | |
238 int found = 0; | |
239 | |
240 *s = 0; | |
241 if (*b != '"') | |
242 return 0; | |
243 b++; | |
244 while (digits--) | |
245 { | |
246 found++; | |
247 if (*b == '"') | |
248 { | |
249 *s = 0; | |
250 b++; | |
251 break; | |
252 } | |
253 if (*b == '\\') | |
254 { | |
255 b = parseHex(2,b+1,(UBYTE *) s); /* ES!! ZERO ? */ | |
256 if (!b) | |
257 return 0; | |
258 s++; | |
259 } | |
260 else | |
261 *s++ = *b++; | |
262 } | |
263 if(*(b-1) NEQ '"') | |
264 return 0; | |
265 *s = 0; /* zero terminated */ | |
266 | |
267 return ((found) ? b : 0); | |
268 } | |
269 | |
270 /* | |
271 +--------------------------------------------------------------------+ | |
272 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
273 | STATE : code ROUTINE : parseNStr | | |
274 +--------------------------------------------------------------------+ | |
275 | |
276 PURPOSE : parse string value and if not numeric returns error | |
277 | |
278 */ | |
279 | |
280 GLOBAL char *parseNStr (int digits, char *b, char *s) | |
281 { | |
282 int found = 0; | |
283 | |
284 *s = 0; | |
285 if (*b != '"') | |
286 return 0; | |
287 b++; | |
288 while (digits-- AND *b AND *b >= 0x20) | |
289 { | |
290 found++; | |
291 if (*b == '"') | |
292 { | |
293 *s = 0; | |
294 b++; | |
295 break; | |
296 } | |
297 if (*b == '\\') | |
298 { | |
299 b = parseHex(2,b+1,(UBYTE *) s); /* ES!! ZERO ? */ | |
300 if (!b) | |
301 return 0; | |
302 s++; | |
303 } | |
304 if ( *b > '9' OR *b < '0') return 0; /*check if numeric value*/ | |
305 else | |
306 *s++ = *b++; | |
307 } | |
308 if(*(b-1) NEQ '"') | |
309 return 0; | |
310 *s = 0; /* zero terminated */ | |
311 | |
312 return ((found) ? b : 0); | |
313 } | |
314 | |
315 /* | |
316 +--------------------------------------------------------------------+ | |
317 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
318 | STATE : code ROUTINE : parseASCII | | |
319 +--------------------------------------------------------------------+ | |
320 | |
321 PURPOSE : parse ASCII value | |
322 | |
323 */ | |
324 | |
325 GLOBAL char *parseASCII (int digits, char *b, char *i) | |
326 { | |
327 int found = 0; | |
328 | |
329 *i = 0; | |
330 while (digits-- AND *b NEQ ' ' AND *b NEQ ',' AND *b NEQ ';' ) | |
331 { | |
332 found++; | |
333 *i = *b; | |
334 i++; | |
335 b++; | |
336 } | |
337 | |
338 return ((found) ? b : 0); | |
339 } | |
340 | |
341 /* | |
342 +--------------------------------------------------------------------+ | |
343 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
344 | STATE : code ROUTINE : parseQASCII | | |
345 +--------------------------------------------------------------------+ | |
346 | |
347 PURPOSE : parse ASCII value and terminate with 0 | |
348 | |
349 */ | |
350 | |
351 GLOBAL char *parseQASCII (int digits, char *b, char *i) | |
352 { | |
353 int found = 0; | |
354 | |
355 *i = 0; | |
356 while (digits-- AND *b NEQ ',' AND *b NEQ ';' AND *b NEQ '\0') | |
357 { | |
358 found++; | |
359 *i = *b; | |
360 i++; | |
361 b++; | |
362 } | |
363 | |
364 if (found) | |
365 { | |
366 *i = 0; | |
367 return (b); | |
368 } | |
369 | |
370 return (NULL); | |
371 } | |
372 | |
373 | |
374 /* | |
375 +--------------------------------------------------------------------+ | |
376 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
377 | STATE : code ROUTINE : parseStrLen | | |
378 +--------------------------------------------------------------------+ | |
379 | |
380 PURPOSE : parse sting, return length and startpoint | |
381 | |
382 */ | |
383 | |
384 GLOBAL char *parseStrLen (USHORT *len, char *b, char **p) | |
385 { | |
386 *len = 0; | |
387 if( *b EQ '"' ) | |
388 b++; | |
389 | |
390 *p = b; | |
391 | |
392 while ( *b NEQ '\0' AND *b NEQ ',' AND *b NEQ ';' AND *b NEQ '"' ) | |
393 { | |
394 (*len)++; | |
395 b++; | |
396 } | |
397 /* needs to process the ending '"' also, otherwise parse returns an error */ | |
398 if( *b EQ '"' ) | |
399 b++; | |
400 | |
401 return ((*len) ? b : 0); | |
402 } | |
403 | |
404 /* | |
405 +--------------------------------------------------------------------+ | |
406 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
407 | STATE : code ROUTINE : parse | | |
408 +--------------------------------------------------------------------+ | |
409 | |
410 PURPOSE : parse AT command parameter | |
411 | |
412 */ | |
413 | |
414 GLOBAL char *parse (char *b, char *f, ...) | |
415 { | |
416 char fc; | |
417 USHORT *i; | |
418 LONG digits=-1; | |
419 BOOL value_is_valid; | |
420 va_list varpars; | |
421 | |
422 va_start (varpars, f); /* Initialize variable arguments. */ | |
423 | |
424 parse_index=0; | |
425 while ((fc = *f++) != 0) | |
426 { | |
427 parse_index++; /* Save the position of current parsing item */ | |
428 value_is_valid = TRUE; | |
429 if (islower(fc)) | |
430 { | |
431 if (*b == 0 OR *b == ';') | |
432 { | |
433 va_end (varpars); /* Reset variable arguments. */ | |
434 return b; | |
435 } | |
436 if (*b == ',') | |
437 { | |
438 b++; | |
439 value_is_valid = FALSE; | |
440 } | |
441 } | |
442 | |
443 switch (toupper(fc)) | |
444 { | |
445 case 'B': | |
446 if (value_is_valid) | |
447 b = parseBin(-1,b,va_arg (varpars, SHORT*)); | |
448 else | |
449 va_arg (varpars, SHORT*); | |
450 break; | |
451 case 'X': | |
452 if (value_is_valid) | |
453 b = parseHex(-1,b,va_arg (varpars, UBYTE*)); | |
454 else | |
455 va_arg (varpars, SHORT*); | |
456 break; | |
457 case 'Y': | |
458 if (value_is_valid) | |
459 b = parseHexToLong(-1,b,va_arg (varpars, LONG*)); | |
460 else | |
461 va_arg (varpars, LONG*); | |
462 break; | |
463 case 'D': | |
464 if (value_is_valid) | |
465 b = parseEnum(-1,b,va_arg (varpars, int*)); | |
466 else | |
467 va_arg (varpars, int*); | |
468 break; | |
469 case 'R': | |
470 if (value_is_valid) | |
471 b = parseShort(-1,b,va_arg (varpars, SHORT*)); | |
472 else | |
473 va_arg (varpars, SHORT*); | |
474 break; | |
475 case 'S': | |
476 if (value_is_valid) | |
477 { | |
478 digits=va_arg (varpars, LONG); | |
479 b = parseStr(digits,b,va_arg (varpars, char*)); | |
480 } | |
481 else | |
482 { | |
483 va_arg (varpars, LONG); | |
484 va_arg (varpars, char*); | |
485 } | |
486 break; | |
487 case 'N': | |
488 if (value_is_valid) | |
489 { | |
490 digits=va_arg (varpars, LONG); | |
491 b = parseNStr(digits,b,va_arg (varpars, char*)); | |
492 } | |
493 else | |
494 { | |
495 va_arg (varpars, LONG); | |
496 va_arg (varpars, char*); | |
497 } | |
498 break; | |
499 case 'Z': | |
500 if (value_is_valid) | |
501 { | |
502 char* c = b; | |
503 USHORT* plen = NULL; | |
504 | |
505 char* cmdPtr; | |
506 USHORT cmdLen; | |
507 | |
508 digits = va_arg ( varpars, LONG ); | |
509 cmdLen = va_arg ( varpars, size_t ); | |
510 cmdPtr = va_arg ( varpars, char* ); | |
511 plen = va_arg ( varpars, USHORT*); | |
512 b = parseZStr | |
513 ( MINIMUM (digits, cmdLen - ( b - cmdPtr )), | |
514 b, va_arg ( varpars, char* ) ); | |
515 | |
516 if ( plen NEQ NULL ) | |
517 { | |
518 if ( b NEQ NULL ) | |
519 *plen = b - c - 2; /* a string always includes two characters '"' */ | |
520 else | |
521 *plen = 0; | |
522 } | |
523 } | |
524 else | |
525 { | |
526 va_arg (varpars, LONG); | |
527 va_arg (varpars, USHORT*); | |
528 va_arg (varpars, char*); | |
529 } | |
530 break; | |
531 case 'A': | |
532 if (value_is_valid) | |
533 { | |
534 digits=va_arg (varpars, LONG); | |
535 b = parseASCII(digits,b,va_arg (varpars, char*)); | |
536 } | |
537 else | |
538 { | |
539 va_arg (varpars, LONG); | |
540 va_arg (varpars, char*); | |
541 } | |
542 break; | |
543 case 'Q': | |
544 if (value_is_valid) | |
545 { | |
546 digits=va_arg (varpars, LONG); | |
547 b = parseQASCII(digits,b,va_arg (varpars, char*)); | |
548 } | |
549 else | |
550 { | |
551 va_arg (varpars, LONG); | |
552 va_arg (varpars, char*); | |
553 } | |
554 break; | |
555 | |
556 case 'L': | |
557 if (value_is_valid) | |
558 { | |
559 i = va_arg(varpars, USHORT*); | |
560 b = parseStrLen (i,b,va_arg(varpars, char**)); | |
561 } | |
562 else | |
563 { | |
564 va_arg (varpars, int*); | |
565 va_arg (varpars, char**); | |
566 } | |
567 break; | |
568 } | |
569 if (!b) | |
570 { | |
571 va_end (varpars); /* Reset variable arguments. */ | |
572 return 0; | |
573 } | |
574 | |
575 if (*f AND *b == ',' AND value_is_valid) | |
576 { | |
577 b++; | |
578 } | |
579 else if (*b AND *b != ';' AND *b != ',' AND value_is_valid) /* if comma or semicolon is missing */ | |
580 { | |
581 TRACE_EVENT ("missing separator detected, aborting parse!"); | |
582 va_end (varpars); | |
583 return 0; | |
584 } | |
585 } | |
586 if (*b AND *b != ';') | |
587 { | |
588 va_end (varpars); /* Reset variable arguments. */ | |
589 return 0; | |
590 } | |
591 va_end (varpars); /* Reset variable arguments. */ | |
592 return b; | |
593 } | |
594 | |
595 | |
596 /* | |
597 +--------------------------------------------------------------------+ | |
598 | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | |
599 | STATE : code ROUTINE : parse | | |
600 +--------------------------------------------------------------------+ | |
601 | |
602 PURPOSE : get last parsed index (to determinate which component was malicious) | |
603 | |
604 */ | |
605 | |
606 GLOBAL UBYTE get_parse_index () | |
607 { | |
608 return parse_index; | |
609 } | |
610 | |
611 | |
612 | |
613 #endif /* ATI_PRS_C */ |