FreeCalypso > hg > fc-magnetite
view src/aci2/aci/ati_prs.c @ 399:a7150a25086a
l1tm_tpu10.c: initial import from MV100 source
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 18 Jan 2018 01:54:27 +0000 |
parents | 93999a60b835 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : GSM-F&D (8411) | Modul : ATI +----------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Purpose : AT Command parameter parser +----------------------------------------------------------------------------- */ #ifndef ATI_PRS_C #define ATI_PRS_C #include "aci_all.h" #include <stdarg.h> #include <ctype.h> #include "aci_cmh.h" #include "ati_cmd.h" #include "aci_cmd.h" #ifdef OPTION_RELATIVE LOCAL ULONG offset; #endif static UBYTE parse_index = 0; /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parseBin | +--------------------------------------------------------------------+ PURPOSE : parse binary value */ GLOBAL char *parseBin (int digits, char *b, SHORT *i) { int found = 0; *i = 0; while (digits-- AND *b >= '0' AND *b <= '1') { found++; *i *= 2; *i += *b - '0'; b++; } return ((found) ? b : 0); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parseHex | +--------------------------------------------------------------------+ PURPOSE : parse hexadecimal value */ GLOBAL char *parseHex (int digits, char *b, UBYTE *i) { int found = 0; *i = 0; while (digits-- AND ((*b >= '0' AND *b <= '9') OR (*b >= 'a' AND *b <= 'f') OR (*b >= 'A' AND *b <= 'F'))) { found++; *i *= 16; if (*b >= '0' AND *b <= '9') *i += *b - '0'; if (*b >= 'a' AND *b <= 'f') *i += *b - 'a' + 10; if (*b >= 'A' AND *b <= 'F') *i += *b - 'A' + 10; b++; } return ((found AND found <= 2) ? b : 0); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parseHexToLong | +--------------------------------------------------------------------+ PURPOSE : parse hexadecimal value */ GLOBAL char *parseHexToLong (int digits, char *b, LONG *i) { *i = 0; while (digits-- AND ((*b >= '0' AND *b <= '9') OR (*b >= 'a' AND *b <= 'f') OR (*b >= 'A' AND *b <= 'F'))) { *i *= 16; if (*b >= '0' AND *b <= '9') *i += *b - '0'; if (*b >= 'a' AND *b <= 'f') *i += *b - 'a' + 10; if (*b >= 'A' AND *b <= 'F') *i += *b - 'A' + 10; b++; } return ( digits EQ 0 ? 0 : b ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parseEnum | +--------------------------------------------------------------------+ PURPOSE : parse enum value */ GLOBAL char *parseEnum (int digits, char *b, int *i) { int found = 0; *i = 0; while (digits-- AND *b >= '0' AND *b <= '9') { found++; *i *= 10; *i += *b - '0'; b++; } return ((found) ? b : 0); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parseShort | +--------------------------------------------------------------------+ PURPOSE : parse Short value */ GLOBAL char *parseShort (int digits, char *b, SHORT *i) { int found = 0; *i = 0; while (digits-- AND *b >= '0' AND *b <= '9') { found++; *i *= 10; *i += *b - '0'; b++; } return ((found) ? b : 0); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parseStr | +--------------------------------------------------------------------+ PURPOSE : parse string value */ GLOBAL char *parseStr (int digits, char *b, char *s) { int found = 0; *s = 0; if (*b != '"') return 0; b++; while (digits-- AND *b AND *b >= 0x20) { found++; if (*b == '"') { *s = 0; b++; break; } if (*b == '\\') { b = parseHex(2,b+1,(UBYTE *) s); /* ES!! ZERO ? */ if (!b) return 0; s++; } else *s++ = *b++; } if(*(b-1) NEQ '"') return 0; *s = 0; /* zero terminated */ return ((found) ? b : 0); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parseZStr | +--------------------------------------------------------------------+ PURPOSE : parse string value */ GLOBAL char *parseZStr (int digits, char *b, char *s) { int found = 0; *s = 0; if (*b != '"') return 0; b++; while (digits--) { found++; if (*b == '"') { *s = 0; b++; break; } if (*b == '\\') { b = parseHex(2,b+1,(UBYTE *) s); /* ES!! ZERO ? */ if (!b) return 0; s++; } else *s++ = *b++; } if(*(b-1) NEQ '"') return 0; *s = 0; /* zero terminated */ return ((found) ? b : 0); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parseNStr | +--------------------------------------------------------------------+ PURPOSE : parse string value and if not numeric returns error */ GLOBAL char *parseNStr (int digits, char *b, char *s) { int found = 0; *s = 0; if (*b != '"') return 0; b++; while (digits-- AND *b AND *b >= 0x20) { found++; if (*b == '"') { *s = 0; b++; break; } if (*b == '\\') { b = parseHex(2,b+1,(UBYTE *) s); /* ES!! ZERO ? */ if (!b) return 0; s++; } if ( *b > '9' OR *b < '0') return 0; /*check if numeric value*/ else *s++ = *b++; } if(*(b-1) NEQ '"') return 0; *s = 0; /* zero terminated */ return ((found) ? b : 0); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parseASCII | +--------------------------------------------------------------------+ PURPOSE : parse ASCII value */ GLOBAL char *parseASCII (int digits, char *b, char *i) { int found = 0; *i = 0; while (digits-- AND *b NEQ ' ' AND *b NEQ ',' AND *b NEQ ';' ) { found++; *i = *b; i++; b++; } return ((found) ? b : 0); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parseQASCII | +--------------------------------------------------------------------+ PURPOSE : parse ASCII value and terminate with 0 */ GLOBAL char *parseQASCII (int digits, char *b, char *i) { int found = 0; *i = 0; while (digits-- AND *b NEQ ',' AND *b NEQ ';' AND *b NEQ '\0') { found++; *i = *b; i++; b++; } if (found) { *i = 0; return (b); } return (NULL); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parseStrLen | +--------------------------------------------------------------------+ PURPOSE : parse sting, return length and startpoint */ GLOBAL char *parseStrLen (USHORT *len, char *b, char **p) { *len = 0; if( *b EQ '"' ) b++; *p = b; while ( *b NEQ '\0' AND *b NEQ ',' AND *b NEQ ';' AND *b NEQ '"' ) { (*len)++; b++; } /* needs to process the ending '"' also, otherwise parse returns an error */ if( *b EQ '"' ) b++; return ((*len) ? b : 0); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parse | +--------------------------------------------------------------------+ PURPOSE : parse AT command parameter */ GLOBAL char *parse (char *b, char *f, ...) { char fc; USHORT *i; LONG digits=-1; BOOL value_is_valid; va_list varpars; va_start (varpars, f); /* Initialize variable arguments. */ parse_index=0; while ((fc = *f++) != 0) { parse_index++; /* Save the position of current parsing item */ value_is_valid = TRUE; if (islower(fc)) { if (*b == 0 OR *b == ';') { va_end (varpars); /* Reset variable arguments. */ return b; } if (*b == ',') { b++; value_is_valid = FALSE; } } switch (toupper(fc)) { case 'B': if (value_is_valid) b = parseBin(-1,b,va_arg (varpars, SHORT*)); else va_arg (varpars, SHORT*); break; case 'X': if (value_is_valid) b = parseHex(-1,b,va_arg (varpars, UBYTE*)); else va_arg (varpars, SHORT*); break; case 'Y': if (value_is_valid) b = parseHexToLong(-1,b,va_arg (varpars, LONG*)); else va_arg (varpars, LONG*); break; case 'D': if (value_is_valid) b = parseEnum(-1,b,va_arg (varpars, int*)); else va_arg (varpars, int*); break; case 'R': if (value_is_valid) b = parseShort(-1,b,va_arg (varpars, SHORT*)); else va_arg (varpars, SHORT*); break; case 'S': if (value_is_valid) { digits=va_arg (varpars, LONG); b = parseStr(digits,b,va_arg (varpars, char*)); } else { va_arg (varpars, LONG); va_arg (varpars, char*); } break; case 'N': if (value_is_valid) { digits=va_arg (varpars, LONG); b = parseNStr(digits,b,va_arg (varpars, char*)); } else { va_arg (varpars, LONG); va_arg (varpars, char*); } break; case 'Z': if (value_is_valid) { char* c = b; USHORT* plen = NULL; char* cmdPtr; USHORT cmdLen; digits = va_arg ( varpars, LONG ); cmdLen = va_arg ( varpars, size_t ); cmdPtr = va_arg ( varpars, char* ); plen = va_arg ( varpars, USHORT*); b = parseZStr ( MINIMUM (digits, cmdLen - ( b - cmdPtr )), b, va_arg ( varpars, char* ) ); if ( plen NEQ NULL ) { if ( b NEQ NULL ) *plen = b - c - 2; /* a string always includes two characters '"' */ else *plen = 0; } } else { va_arg (varpars, LONG); va_arg (varpars, USHORT*); va_arg (varpars, char*); } break; case 'A': if (value_is_valid) { digits=va_arg (varpars, LONG); b = parseASCII(digits,b,va_arg (varpars, char*)); } else { va_arg (varpars, LONG); va_arg (varpars, char*); } break; case 'Q': if (value_is_valid) { digits=va_arg (varpars, LONG); b = parseQASCII(digits,b,va_arg (varpars, char*)); } else { va_arg (varpars, LONG); va_arg (varpars, char*); } break; case 'L': if (value_is_valid) { i = va_arg(varpars, USHORT*); b = parseStrLen (i,b,va_arg(varpars, char**)); } else { va_arg (varpars, int*); va_arg (varpars, char**); } break; } if (!b) { va_end (varpars); /* Reset variable arguments. */ return 0; } if (*f AND *b == ',' AND value_is_valid) { b++; } else if (*b AND *b != ';' AND *b != ',' AND value_is_valid) /* if comma or semicolon is missing */ { TRACE_EVENT ("missing separator detected, aborting parse!"); va_end (varpars); return 0; } } if (*b AND *b != ';') { va_end (varpars); /* Reset variable arguments. */ return 0; } va_end (varpars); /* Reset variable arguments. */ return b; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : ACI_PRS | | STATE : code ROUTINE : parse | +--------------------------------------------------------------------+ PURPOSE : get last parsed index (to determinate which component was malicious) */ GLOBAL UBYTE get_parse_index () { return parse_index; } #endif /* ATI_PRS_C */