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