diff g23m-aci/aci/ati_prs.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/g23m-aci/aci/ati_prs.c	Thu Jun 09 00:02:41 2016 +0000
@@ -0,0 +1,1095 @@
+/* 
++----------------------------------------------------------------------------- 
+|  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 "config.h"
+#include "fixedconf.h"
+#include "condat-features.h"
+#include "aci_conf.h"
+
+#include "aci_all.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#include "aci_cmh.h"
+#include "ati_cmd.h"
+#include "aci_cmd.h"
+#include "aci_prs.h"
+
+#ifdef GPRS
+  #include "gaci_cmh.h"
+#endif /* GPRS */
+
+#include "aci_lst.h"
+#include "ati_int.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 NEQ '"')
+        return 0;
+    b++;
+    while (digits-- AND *b AND *b >= 0x20)
+    {
+        found++;
+        if (*b EQ '"')
+        {
+            *s = 0;
+            b++;
+            break;
+        }
+        if (*b EQ '\\')
+        {
+            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 NEQ '"')
+        return 0;
+    b++;
+    while (digits--)
+    {
+        found++;
+        if (*b EQ '"')
+        {
+            *s = 0;
+            b++;
+            break;
+        }
+        if (*b EQ '\\')
+        {
+            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 NEQ '"')
+        return 0;
+    b++;
+    while (digits-- AND *b AND *b >= 0x20)
+    {
+        found++;
+        if (*b EQ '"')
+        {
+            *s = 0;
+            b++;
+            break;
+        }
+        if (*b EQ '\\')
+        {
+            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++;
+
+  /* Check if the string is a null string like "" */
+  if( *b EQ '"' )
+  {
+    b++;
+
+   /* return new buffer position without setting p, thereby omitting the parameter */
+    return b; 
+  }
+
+  *p = b;
+
+  while ( *b NEQ '\0' AND *b NEQ ',' AND *b NEQ ';' AND *b NEQ '"' )
+  {
+    (*len)++;
+    b++;
+  }
+ 
+  if(*b EQ '"')
+  {
+    b++;
+  }
+
+  return ((*len) ? b : 0);
+}
+
+
+#ifdef GPRS
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ACI_PRS            |
+| STATE   : devellopment                ROUTINE : parseExpo          |
++--------------------------------------------------------------------+
+
+  PURPOSE : parse exponential expresion (ex. 2E3)
+
+*/
+
+GLOBAL char *parseExpo( int digits, char *b, T_PS_ber *e )
+{
+  BOOL valid = FALSE;
+
+  e->ratio_mant = 0;
+  e->ratio_exp  = 0;
+  if( *b EQ '"' ) /* start of string */
+  {
+    b++;
+    while( digits-- AND *b >= '0' AND *b <= '9' )
+    {
+      e->ratio_mant *= 10;
+      e->ratio_mant += *b - '0';
+      b++;
+    }
+    if( *b EQ 'E' )
+    {
+      b++;
+      while( digits-- AND *b >= '0' AND *b <= '9' )
+      {
+        e->ratio_exp *= 10;
+        e->ratio_exp += *b - '0';
+        b++;
+        valid = TRUE;
+      }
+      
+      if( *b EQ '"' ) /* end of string */
+      {
+        b++;
+      }
+      else
+      {
+        valid = FALSE;
+      }
+      	
+    }
+    else
+    {
+      valid = FALSE;
+    }
+  }
+  else
+  {
+    valid = FALSE;
+  }
+
+  return ((valid) ? b : 0);
+
+} /* END parseExpo(...) */
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ACI_PRS            |
+| STATE   : Finished                    ROUTINE : parseCid_list      |
++--------------------------------------------------------------------+
+
+  PURPOSE : Parse a list of Cids. If the parsing is sucessfull the 
+            number of parsed cids is returned otherwise -1 is returned.
+
+*/
+GLOBAL char *parseCid_list(char *b, U8 *cid_list_length, U8 *cid_list)
+{
+  U8    no_of_cids;
+  char *end;
+
+  /* Parse all cids into the cid_list */
+  no_of_cids = 0;
+  do
+  {
+
+    /* If it's not the first cid remove the "," */
+    if( no_of_cids )
+      b++;
+
+    /* Set the entry to omitted. */
+    cid_list[no_of_cids] = PDP_CONTEXT_CID_OMITTED;
+
+    /* Parse the value */
+    cid_list[no_of_cids] = (U8) strtol( b, &end, 10 );
+    b = end;
+
+    /* If a cid is omitted no cids must be specified at all. */
+    if( cid_list[no_of_cids] EQ PDP_CONTEXT_CID_OMITTED )
+    {
+      if( no_of_cids NEQ 0 )
+      {
+        /* Don't accept omitted cids inside if it's not the first (ex. 1,,2,3 is not allowed). */
+        cmdCmeError( CME_ERR_OpNotSupp );
+        return( NULL );
+      }
+      /* Break the while */
+      break;
+    }
+    if( (!b) OR 
+        (cid_list[no_of_cids] <  PDP_CONTEXT_CID_MIN) OR 
+        (cid_list[no_of_cids] >  PDP_CONTEXT_CID_MAX) OR 
+        (no_of_cids           >= PDP_CONTEXT_CID_MAX) )
+    {
+      cmdCmeError( CME_ERR_OpNotSupp );
+      return( NULL );
+    }
+    no_of_cids++;
+  }
+  
+  while( *b EQ ','  AND
+    no_of_cids < *cid_list_length );
+  
+  cid_list[no_of_cids+1] = PDP_CONTEXT_CID_INVALID;
+
+  *cid_list_length = no_of_cids;
+  return( b );
+
+}
+
+#endif /* GPRS */
+
+/*
++----------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_PRS              |
+| STATE   : -                           ROUTINE : parsePointerToString |
+-----------------------------------------------------------------------+
+
+  PURPOSE : Parse pointer to input string. returns pointer to end of string.
+
+*/
+GLOBAL char *parsePointerToString(char chars, char *b, char **p_begin)
+{
+  if( b AND *b EQ '"' )
+  {
+    b++;
+    *p_begin = b;
+    
+    while (chars-- AND *b AND *b NEQ '"')
+    {
+      b++;
+    }
+    if( *b EQ '"' )
+    {
+      b++;
+    }
+    else
+    {
+      if( !chars )
+      {
+        b = NULL;
+      }
+    }
+  }
+
+  return b;
+}
+
+/*
++----------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_PRS              |
+| STATE   : -                           ROUTINE : StrToU16             |
+-----------------------------------------------------------------------+
+
+  PURPOSE : Parse string value to U16.
+
+*/
+
+char *StrToU16(char *p_str, U16 *p_result)
+{
+  U32 val = 0;
+  
+  if( p_str )
+  {
+    if( *p_str >= '0' AND *p_str <= '9' )
+    {
+      while( *p_str >= '0' AND *p_str <= '9' )
+      {
+        val *= 10;
+        val += (int)(*p_str - '0');
+        p_str++;
+      }
+    }
+  }
+
+  if( val <= 0xffff ) /* 0xffff = max value of U16 */
+  	*p_result = (U16)(val);
+  else
+  	p_str = NULL;
+  
+  return p_str;
+  
+}
+
+/*
++---------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_PRS             |
+| STATE   : -                           ROUTINE : parseDSNP_U16       |
+----------------------------------------------------------------------+
+
+  PURPOSE : parse dot-separated numeric parameters from the 
+            input string to an array of U8.
+            
+            ex. input p_in = "192.124.13.3"
+                output p_out = {192,124,13,3} 
+
+*/
+GLOBAL char *parseDSNP_U16( char blocks, char *p_in, U16 *p_out )
+{
+  if( p_in AND p_out )
+  {
+    if( *p_in EQ '.' ) p_in++;
+    while( blocks-- AND *p_in NEQ 0x00 )
+    {
+      p_in = StrToU16(p_in, p_out);
+      
+      if( p_in AND blocks AND *p_in EQ '.' )
+      {
+        p_in++;
+        p_out++;
+      }
+      else
+        break;
+    }
+  }
+  return p_in;
+}
+
+/*
++---------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_PRS             |
+| STATE   : -                           ROUTINE : parseIPv4Address    |
+----------------------------------------------------------------------+
+*/
+GLOBAL char *parseIPv4Address(char *p_in, U8 * p_ip_addr, U8 * is_ip_valid)
+{
+  U16  ip_addr[4];
+  char i;
+  char *p_out = NULL;
+
+  if( p_in AND p_ip_addr )
+  {
+    p_out = parseDSNP_U16(4, p_in, ip_addr);
+    for(i=0; i<4; i++)
+    {
+      if(ip_addr[i] <= 255)
+      {
+        p_ip_addr[i] = (U8) ip_addr[i];
+      }
+      else
+      {
+        p_out = NULL;
+      }
+
+    }
+  }
+  * is_ip_valid = (p_out NEQ NULL);
+
+  return p_out;
+}
+
+/*
++---------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_PRS             |
+| STATE   : -                           ROUTINE : parseIPv6Address    |
+----------------------------------------------------------------------+
+*/
+GLOBAL char *parseIPv6Address(char *p_in, U8 *p_ip_addr, U8 * is_ip_valid)
+{
+  U16  ip_addr[16];
+  char i;
+  char *p_out = NULL;
+
+  if( p_in AND p_ip_addr )
+  {
+    p_out = parseDSNP_U16(16, p_in, ip_addr);
+    for(i=0; i<16; i++)
+    {
+      if(ip_addr[i] > 255)
+        p_out = NULL;
+      else
+        p_ip_addr[i] = (U8) ip_addr[i];
+    }
+  }
+
+  * is_ip_valid = (p_out NEQ NULL);
+
+  return p_out;
+}
+
+/*
++--------------------------------------------------------------------+
+| 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;
+
+#ifdef GPRS
+  U8      *j;
+#endif /* GPRS */
+  LONG    digits = -1;
+  BOOL value_is_valid;
+ /*lint -e516 -e10*/
+  va_list varpars;
+
+  va_start (varpars, f);        /* Initialize variable arguments. */
+
+  parse_index=0;
+  while ((fc = *f++) NEQ 0)
+  {
+    parse_index++;              /* Save the position of current parsing item */
+    value_is_valid = TRUE;
+    if (islower(fc))
+    {
+      if (*b EQ 0 OR *b EQ ';')
+      {
+        va_end (varpars);        /* Reset variable arguments.      */
+        return b;
+      }
+      if (*b EQ ',')
+      {
+        b++;
+        value_is_valid = FALSE;
+      }
+    }
+
+    switch (toupper(fc))
+    {
+      case 'B':
+        if (value_is_valid)
+          b = parseBin(-1,b,va_arg (varpars, short*));
+        else
+          (void)va_arg (varpars, short*);
+        break;
+      
+      case 'X':
+        if (value_is_valid)
+          b = parseHex(-1,b,va_arg (varpars, unsigned char*));
+        else
+          (void)va_arg (varpars, short*);
+        break;
+      
+      case 'Y':
+        if (value_is_valid)
+          b = parseHexToLong(-1,b,va_arg (varpars, long*));
+        else
+          (void)va_arg (varpars, short*);
+        break;
+      
+      case 'D':
+        if (value_is_valid)
+          b = parseEnum(-1,b,va_arg (varpars, int*));
+        else
+          (void)va_arg (varpars, int*);
+        break;
+      
+      case 'R':
+        if (value_is_valid)
+          b = parseShort(-1,b,va_arg (varpars, short*));
+        else
+          (void)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
+        {
+          (void)va_arg (varpars, long);
+          (void)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
+        {
+          (void)va_arg (varpars, long);
+          (void)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, unsigned );
+          cmdPtr = va_arg ( varpars, char* );
+          plen   = va_arg ( varpars, unsigned short*);
+          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
+        {
+          (void)va_arg (varpars, long);
+          (void)va_arg (varpars, unsigned short*);
+          (void)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
+        {
+          (void)va_arg (varpars, long);
+          (void)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
+        {
+          (void)va_arg (varpars, long);
+          (void)va_arg (varpars, char*);
+        }
+        break;
+
+      case 'L':
+        if (value_is_valid)
+        {
+          i = va_arg(varpars, unsigned short*);
+          b = parseStrLen (i,b,va_arg(varpars, char**));
+        }
+        else
+        {
+          (void)va_arg (varpars, int*);
+          (void)va_arg (varpars, char**);
+        }
+        break;
+
+#ifdef GPRS
+
+      case 'E':
+        if (value_is_valid)
+        {/*lint -e78 -e26 -e530*/
+          b = parseExpo( -1, b, va_arg(varpars, T_PS_ber*));
+        }
+        else
+        {
+          (void)va_arg (varpars, T_PS_ber*);
+        }
+        break;
+
+#endif
+
+      case 'C':
+        if (value_is_valid)
+        {
+          b = parseByte( -1, b, va_arg(varpars, unsigned char*));
+        }
+        else
+        {
+          (void)va_arg (varpars, unsigned char*);
+        }
+        break;
+
+#ifdef GPRS
+
+      case 'I': /* Parse cid_list */
+        if( value_is_valid )
+        {
+          j = va_arg(varpars, unsigned char*);
+
+          b = parseCid_list( b, j, va_arg(varpars, unsigned char*) );
+        }
+        break;
+#endif /* GPRS */
+
+      case 'P': /* Parse pointer to string */
+        if( value_is_valid )
+        {
+          b = parsePointerToString( (char)-1, b, va_arg(varpars, char**) );
+        }
+        break;
+
+      case '*': /* Parse '*' */
+        if( value_is_valid )
+        {
+          if( *b NEQ '*' )
+          {
+            return 0;
+          }
+          b++;
+        }
+        break;
+
+      case '#': /* Parse '#' */
+        if( value_is_valid )
+        {
+          if( *b NEQ '#' )
+          {
+            return 0;
+          }
+          b++;
+        }
+        break;
+     }
+    if (!b)
+    {
+      va_end (varpars);              /* Reset variable arguments.      */
+      return 0;
+    }
+
+    if (*f AND *b EQ ',' AND value_is_valid)
+    {
+      b++;
+    }
+    else if (*b AND *b NEQ ';' AND *b NEQ ',' 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 NEQ ';')
+  {
+    va_end (varpars);              /* Reset variable arguments.      */
+    return 0;
+  }
+  va_end (varpars);              /* Reset variable arguments.      */
+ /*lint +e516 +e10*/
+  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;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_PRS            |
+| STATE   : code                        ROUTINE : parseByte(U8)      |
++--------------------------------------------------------------------+
+
+  PURPOSE : parse U8 value
+
+*/
+
+GLOBAL char *parseByte (int digits, char *b, U8 *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 : parseTimeStamp              |
++--------------------------------------------------------------------+
+
+  PURPOSE : Parse time stamp format in "yy/MM/dd,hh:mm:ss±zz"
+
+*/
+
+GLOBAL UBYTE parseTimeStamp( char *p_in,U8 *years,U8 *months,U8 *days,
+                             U8 *hrs, U8 *mins,U8 *secs, char *sign, U8 *time_zone )
+{
+  if( p_in[2] NEQ '/' OR  p_in[5] NEQ '/' OR p_in[8] NEQ ',' OR p_in[11] NEQ ':' OR p_in[14] NEQ ':' )
+  {
+    return NO_TIME_STAMP_FIELD;
+  }
+  if(!parseByte (2, &p_in[0], years))
+  {
+    return NO_TIME_STAMP_FIELD;
+  }
+  if(!parseByte (2, &p_in[3], months))
+  {
+    return NO_TIME_STAMP_FIELD;
+  }
+  if(!parseByte (2, &p_in[6], days))
+  {
+    return NO_TIME_STAMP_FIELD;
+  }
+  if(!parseByte (2, &p_in[9], hrs))
+  {
+    return NO_TIME_STAMP_FIELD;
+  }
+  if(!parseByte (2, &p_in[12], mins))
+  {
+    return NO_TIME_STAMP_FIELD;
+  }
+  if(!parseByte (2, &p_in[15], secs))
+  {
+    return NO_TIME_STAMP_FIELD;
+  }
+  *sign = p_in[17];
+
+  if(*sign NEQ '+' AND  *sign NEQ '-' )
+  {
+    return NO_TIME_STAMP_FIELD;
+  }
+  if(!parseByte (2, &p_in[18], time_zone))
+  {
+    return NO_TIME_STAMP_FIELD;
+  }
+
+ return MAX_TIME_STAMP_FIELDS; 
+}
+
+#endif /* ATI_PRS_C */