FreeCalypso > hg > fc-magnetite
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/aci2/aci/ati_prs.c Mon Sep 26 00:29:36 2016 +0000 @@ -0,0 +1,613 @@ +/* ++----------------------------------------------------------------------------- +| 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 */ \ No newline at end of file