diff gsm-fw/ccd/asn1_seq.c @ 648:970d6199f2c5

gsm-fw/ccd/*.[ch]: initial import from the LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 04 Sep 2014 05:48:57 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/ccd/asn1_seq.c	Thu Sep 04 05:48:57 2014 +0000
@@ -0,0 +1,615 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  
+|  Modul   : asn1_seq.c
++----------------------------------------------------------------------------- 
+|  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 :  Definition of encoding and decoding functions for ASN1_SEQUENCE
+|             elements 
++----------------------------------------------------------------------------- 
+*/ 
+
+#define ASN1_SEQ_C
+
+/*
+ * Standard definitions like UCHAR, ERROR etc.
+ */
+#include "typedefs.h"
+#include "header.h"
+
+/*
+ * Prototypes of ccd (USE_DRIVER EQ undef) for prototypes only
+ * look at ccdapi.h
+ */
+#undef USE_DRIVER
+#include "ccdapi.h"
+
+/*
+ * Types and functions for bit access and manipulation
+ */
+#include "ccd_globs.h"
+#include "bitfun.h"
+
+/*
+ * Prototypes and constants in the common part of ccd
+ */
+#include "ccd.h"
+#include "ccd_codingtypes.h"
+
+/*
+ * Declaration of coder/decoder tables
+ */
+#include "ccdtable.h"
+#include "ccddata.h"
+
+EXTERN T_FUNC_POINTER codec[MAX_CODEC_ID+1][2];
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)              MODULE  : asn1_seq               |
+| STATE   : code                    ROUTINE : Read_SEQ_BitMap        |
++--------------------------------------------------------------------+
+
+  PURPOSE : Decode the bit-map preamble for OPTIONAL elements 
+            or those with DEFAULT value.
+*/
+void Read_SEQ_BitMap (const ULONG first_elem, const ULONG last_elem, T_CCD_Globs *globs)
+{
+  ULONG elem = first_elem;
+  while (elem < last_elem)
+  {
+    if (melem[elem].optional)
+    {
+      /* 
+       * For optional elements read the corresponding bit in the preamble
+       * and set the valid flag in the C-Structure to it.
+       */             
+      if (melem[elem].elemType < 'P' OR melem[elem].elemType > 'R')
+      {
+        globs->pstruct[melem[elem].structOffs] = (UBYTE) bf_readBit(globs);
+      }
+      else
+      {
+        if(bf_readBit(globs)) /*elemType P, Q or R*/
+        {
+          /*If present set the pointer to -1 (0xFFFF) - anything else than NULL, because the 
+          element is present*/
+          *(void**) &globs->pstruct[melem[elem].structOffs] = (void *) 0xFFFF;
+        }
+        else /*Not present set the pointer to NULL*/
+          *(void**) &globs->pstruct[melem[elem].structOffs] = NULL;
+      
+      }
+    }
+    /* 
+     * For optional elements read the corresponding bit in the preamble
+     * and set the valid flag in the C-structure to it.
+     */
+    else if (melem[elem].codingType EQ CCDTYPE_ASN1_INTEGER)
+    {       
+      /* 
+       * Check if this variable has a default value.
+       * As long as the DEFAULT values are given with ranges it is right to
+       * look for isDefault in the second entry in mval.cdg.
+       * There is no valid flag for elements with default value. But we use
+       * the first byte of this element within the C-structure for giving a
+       * signal to this function. The only simple type which has DEFAULT is INTEGER.
+       */
+      if (mval[mvar[melem[elem].elemRef].valueDefs+1].isDefault EQ 2)
+      {
+        globs->pstruct[melem[elem].structOffs] = (UBYTE) bf_readBit(globs);
+      }           
+    }
+    elem++;
+  }
+}
+#endif /* !RUN_INT_RAM */
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)              MODULE  : CDC_GSM                |
+| STATE   : code                    ROUTINE : cdc_asn1_seq_decode    |
++--------------------------------------------------------------------+
+
+  PURPOSE : Decoding of the SEQUENCE and SEQUENCE OF type for UMTS
+            The element can be a field of fixed or variable length.
+            It can contain OPTIONAL elements or integer elements with 
+            a DEFAULT value. 
+            A special case is when the element is a so called msg_data. 
+            According to CCDDATA a message is made of a msg_type and 
+            a msg_data part. If the msg_data has a coding type of 
+            ASN1_SEQUENCE this function is called.
+            In this case CCD needs to pass over the msg_type by 
+            incrementing globs->pstruct. A msg_data sequence can not 
+            be optional. Nor it can be an array of msg_data. 
+            If the sequence is not a msg_data this function is called 
+            as an equivalent to ccd_decodeComposition. Hence the 
+            increment on globs->ccd_recurs_level. A non-msg_data 
+            sequence can be optional or an array.    
+*/ 
+SHORT cdc_asn1_seq_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
+{
+  ULONG  repeat=1, max_rep=1; 
+  ULONG  cSize, first_elem, last_elem, elem;
+  UBYTE  *old_pstruct;
+#ifdef DEBUG_CCD
+	static S8 trace_nesting_level = -1;
+#endif
+
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "cdc_asn1_seq_decode()");
+	#else
+	TRACE_CCD (globs, "cdc_asn1_seq_decode() %s", mcomp[melem[e_ref].elemRef].name);
+	#endif
+#endif
+
+  /* 
+   * This function is called as an equivalent to ccd_decodeComposition.  
+   * Hence the increment on globs->ccd_recurs_level.
+   */
+  globs->ccd_recurs_level ++;
+
+  /* 
+   * Set pstrcutOffs and max_rep. 
+   * Check the valid flag in case of optional elements.
+   */
+  if (PER_CommonBegin (e_ref, &max_rep, globs) NEQ ccdOK)
+  {
+    globs->ccd_recurs_level --;
+    return 1;
+  }
+
+  /*
+   * Prepare for decoding of the same sequence type up to max_rep times.
+   * Set the upper and lower bound of elemRef for processing of each repeatition.
+   * Read the C-size to go ahead in the C-structure after each repeatition.
+   */
+  switch (melem[e_ref].elemType)
+  {
+    case 'C':
+    case 'D':
+    case 'E':
+    case 'P':
+    case 'Q':
+              elem       = (ULONG) melem[e_ref].elemRef;
+              first_elem = (ULONG) mcomp[elem].componentRef;
+              last_elem  = first_elem + mcomp[elem].numOfComponents;
+              cSize      = (ULONG) mcomp[elem].cSize;
+              break;
+    case 'F':
+    case 'R':
+              first_elem = e_ref;
+              last_elem  = e_ref + 1;
+              cSize      = (ULONG) mvar[e_ref].cSize;
+              break;
+    default:
+              ccd_setError (globs, ERR_DEFECT_CCDDATA, BREAK, 
+                        (USHORT) (globs->bitpos), (USHORT) -1);
+              return 1;
+         
+  };
+  /*
+   * Store the current value of the C-structure pointer.  
+   * After decoding the SEQUENCE component we will set the pointer 
+   * to this stored value. Then we will use pstructOffs for pointing   
+   * to the next element.
+   */
+  old_pstruct = globs->pstruct;
+#ifdef DYNAMIC_ARRAYS
+  /*
+   * Allocate memory for this whole composition, if elemType is
+   * one of the pointer types.
+   */
+  if ( is_pointer_type(e_ref))
+  {
+    if ( PER_allocmem_and_update(e_ref, max_rep, globs) NEQ ccdOK )
+    {
+    /* No memory - Return.  Error already set in function call above. */
+    globs->ccd_recurs_level --;
+    return 1;
+    }
+
+  }
+#endif
+  globs->pstruct += globs->pstructOffs;
+
+  /*
+   * Decode all elements of the field.
+   */
+  while (repeat <= max_rep)
+  {
+    Read_SEQ_BitMap (first_elem, last_elem, globs);
+    elem = first_elem;
+    
+    /*
+     * Decode all elements of the array
+     */
+#ifdef DEBUG_CCD
+		trace_nesting_level++;
+#endif
+    while (elem < last_elem)
+    {
+#ifdef ERR_TRC_STK_CCD
+      /* 
+       * Save the value for tracing in error case.
+       */
+      globs->error_stack[globs->ccd_recurs_level] = (USHORT) elem;
+#endif /* ERR_TRC_STK_CCD */
+
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+		TRACE_CCD (globs, "decoding level %d element %d", trace_nesting_level, elem - first_elem);
+	#else
+    TRACE_CCD (globs, "decoding level %d element %d '%s'",trace_nesting_level, elem - first_elem, ccddata_get_alias((USHORT) elem, 1));
+	#endif
+#endif
+
+      /*
+       * Use the jump-table for selecting the decode function.
+       * Possible types are 0, ASN1_INTEGER, BITSTRING, ASN1_CHOICE and 
+       * ASN1_SEQUENCE. In case of 0 function cdc_STD_decode will be called.
+       */
+			(void) codec[melem[elem].codingType][DECODE_FUN]
+                                            (c_ref, elem, globs);
+      elem ++;
+    }
+#ifdef DEBUG_CCD
+		trace_nesting_level--;
+#endif
+
+    /*
+     * Set the pointer of the C-structure on the next element.
+     */
+    globs->pstruct += cSize; 
+
+    repeat ++;
+  }
+
+  /*
+   * Prepare for decoding the next element.
+   */
+  globs->pstruct = old_pstruct;
+  globs->ccd_recurs_level--;
+
+  return 1;
+}
+#endif /* !RUN_INT_RAM */
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)              MODULE  : asn1_seq               |
+| STATE   : code                    ROUTINE : Write_SEQ_BitMap       |
++--------------------------------------------------------------------+
+
+  PURPOSE : Encode the bit-map preamble for OPTIONAL elements 
+            or those with DEFAULT value.
+*/
+void Write_SEQ_BitMap (const ULONG first_elem, const ULONG last_elem, T_CCD_Globs *globs)
+{
+  ULONG elem = first_elem;
+    while (elem < last_elem)
+    {
+      if (melem[elem].optional)
+      {
+        /* 
+         * For optional elements read the valid flag in the C-Structure  
+         * and overwrite the corresponding bit in the preamble.
+         */             
+
+#if defined _TOOLS_
+        int patch;
+        U16 stelem;
+        stelem = globs->error_stack[globs->ccd_recurs_level];
+        globs->error_stack[globs->ccd_recurs_level] = (USHORT) elem;
+        patch = ccd_patch (globs, 1);
+        globs->error_stack[globs->ccd_recurs_level] = stelem;
+        if (patch)
+        {
+          bf_writeBit(1, globs);
+          elem++;
+          continue;
+        }
+#endif /* _TOOLS_ */
+
+#ifdef DYNAMIC_ARRAYS
+	    if ( is_pointer_type(elem) )
+      {
+	      BOOL   present;
+	      /*
+	       * Check for NULL pointer (== notPresent/not valid) for this element.
+	       */
+	      present = (*(U8 **)(globs->pstruct + melem[elem].structOffs) NEQ NULL);
+	      /*
+	       * Double check for 'D' to 'F' types. Both NULL pointer and
+	       * valid flag. (Strictly not necessary, but may catch uninitialized
+	       * flags/pointers).
+	       */
+	      if (present AND (melem[elem].elemType >= 'D' AND
+			       melem[elem].elemType <= 'F')) 
+        {
+	        present = (BOOL)globs->pstruct[melem[elem].structOffs];
+	      }
+	      bf_writeBit(present, globs);
+	    } 
+      else
+#endif
+	      bf_writeBit((BOOL)globs->pstruct[melem[elem].structOffs], globs);
+      }
+      else if (melem[elem].codingType EQ CCDTYPE_ASN1_INTEGER)
+      {       
+        /* 
+         * Check if this variable has a default value.
+         * As long as the DEFAULT values are given with ranges it is right to
+         * look for isDefault in the second entry in mval.cdg.
+         * There is no valid flag for elements with default value. So we need
+         * to read the value from C-structure and compare it with the DEFAULT 
+         * value given in the mval table. The only simple type which has 
+         * DEFAULT is INTEGER. 
+         */
+        if (mval[mvar[melem[elem].elemRef].valueDefs+1].isDefault EQ 2)
+        {
+          U32 value=0;
+          UBYTE *p;
+          /*
+           * setup the read pointer to the element in the C-structure
+           */
+#ifdef DYNAMIC_ARRAYS
+          if ( is_pointer_type(elem) )
+          {
+            /*
+             * NULL pointers should be caught as part of the optionality
+             * check in PER_CommonBegin()
+             */
+            p = *(U8 **)(globs->pstruct + globs->pstructOffs);
+            if (ccd_check_pointer(p) != ccdOK)
+            {
+               ccd_recordFault (globs, ERR_INVALID_PTR, BREAK, (USHORT) elem, 
+                                &globs->pstruct[globs->pstructOffs]);
+               return;
+            }
+          }
+          else
+#endif
+          p = globs->pstruct + melem[elem].structOffs;
+          /*
+           * Default values are all positive and small values (< 64K)
+           * in the current version of umts. The cases 'L' and 'C' are added
+           * to be ready for a future change where we need also a check of
+           * possible errors through type casting.
+           */
+          switch (mvar[melem[elem].elemRef].cType)
+          {
+            case 'B':
+                      value = (U32)*(UBYTE *) p;
+                      break;
+            case 'C':
+                      value = (U32)(S32)*(S8 *) p;
+                      break;
+            case 'S':
+                      value = (U32)(*(USHORT *) p);
+                      break;
+            case 'T':
+                      value = (U32)(S32)*(S16 *) p;
+                      break;
+            case 'L':
+                      value = (U32)*(S32 *) p;
+                      break;
+            case 'M':
+                      value = (U32)*(U32 *) p;
+                      break;
+            default:
+                      ccd_setError (globs, ERR_DEFECT_CCDDATA, BREAK, (USHORT) -1);
+                      break;
+          }
+          /* 
+           * Compare the value to be encoded with the default value. 
+           * Write the presence flag into the preamble.
+           */
+          if (value EQ (U32)mval[mvar[melem[elem].elemRef].valueDefs+1].startValue)
+          {
+            bf_writeBit(0, globs);
+          }
+          else
+          {
+            bf_writeBit(1, globs);
+          }
+        }           
+      }
+      elem++;
+    }
+}
+#endif /* !RUN_INT_RAM */
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)              MODULE  : CDC_GSM                |
+| STATE   : code                    ROUTINE : cdc_asn1_seq_encode    |
++--------------------------------------------------------------------+
+
+  PURPOSE : Decoding of the SEQUENCE and SEQUENCE OF type for UMTS
+            The element can be a field of fixed or variable length.
+            It can contain OPTIONAL elements or integer elements with 
+            a DEFAULT value. 
+            A special case is when the element is a so called msg_data. 
+            According to CCDDATA a message is made of a msg_type and 
+            a msg_data part. If the msg_data has a coding type of 
+            ASN1_SEQUENCE this function is called.
+            In this case CCD needs to pass over the msg_type by 
+            incrementing globs->pstruct. A msg_data sequence can not 
+            be optional. Nor it can be an array of msg_data. 
+            If the sequence is not a msg_data this function is called 
+            as an equivalent to ccd_encodeComposition. Hence the 
+            increment on globs->ccd_recurs_level. A non-msg_data 
+            sequence can be optional or an array.
+*/
+SHORT cdc_asn1_seq_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
+{
+  ULONG  repeat=1, max_rep=1; 
+  ULONG  cSize, first_elem, last_elem, elem;
+  UBYTE  *old_pstruct;
+#ifdef DEBUG_CCD
+	static S8 trace_nesting_level = -1;
+#endif
+
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "cdc_asn1_seq_encode()");
+	#else
+	TRACE_CCD (globs, "cdc_asn1_seq_encode() %s", mcomp[melem[e_ref].elemRef].name);
+	#endif
+#endif
+
+  /* 
+   * This function is called as an equivalent to ccd_encodeComposition.
+   * Hence the increment on globs->ccd_recurs_level.
+   */
+  globs->ccd_recurs_level ++;
+
+  /* 
+   * Set pstrcutOffs and max_rep. 
+   * Check the valid flag in case of optional elements.
+   */
+  if (PER_CommonBegin (e_ref, &max_rep, globs) NEQ ccdOK)
+  {
+    globs->ccd_recurs_level --;
+    return 1;
+  }
+
+  /*
+   * Prepare for encoding of the same sequence type up to max_rep times.
+   * Set the upper and lower bound of elemRef for processing of each repeatition.
+   * Read the C-size to go ahead in the C-structure after each repeatition.
+   */ 
+  switch (melem[e_ref].elemType)
+  {
+    case 'C':
+    case 'D':
+    case 'E':
+    case 'P':
+    case 'Q':
+    {
+              elem       = (ULONG) melem[e_ref].elemRef;
+              first_elem = (ULONG) mcomp[elem].componentRef;
+              last_elem  = first_elem + mcomp[elem].numOfComponents;
+              cSize      = (ULONG) mcomp[elem].cSize;
+              break;
+    }
+    case 'F':
+    case 'R':
+    {
+              first_elem = e_ref;
+              last_elem  = e_ref + 1;           
+              cSize      = (ULONG) mvar[e_ref].cSize;
+              break;
+    }
+    default:
+              ccd_setError (globs, ERR_DEFECT_CCDDATA, BREAK, 
+                        (USHORT) (globs->bitpos), (USHORT) -1);
+              return 1;
+         
+  }
+  /*
+   * Store the current value of the C-structure pointer.  
+   * After encoding the SEQUENCE component we will set the pointer 
+   * to this stored value. Then we will use pstructOffs for pointing
+   * to the next element.  
+   */  
+  old_pstruct = globs->pstruct;
+  globs->pstruct += globs->pstructOffs;
+
+#ifdef DYNAMIC_ARRAYS
+  if ( is_pointer_type(e_ref) ) {
+    if (ccd_check_pointer(*(U8 **)globs->pstruct) == ccdOK)
+    {
+      globs->pstruct = *(U8 **) globs->pstruct;
+    }
+    else
+    {
+       ccd_recordFault (globs, ERR_INVALID_PTR, BREAK, (USHORT) e_ref, 
+                        &globs->pstruct[globs->pstructOffs]);
+       return 1;
+    }
+  }
+#endif
+
+
+  /*
+   * Encode all elements of the field.
+   */
+  while (repeat <= max_rep)
+  { 
+    Write_SEQ_BitMap (first_elem, last_elem, globs); 
+
+    /*
+     * Encode all elements
+     */
+#ifdef DEBUG_CCD
+		trace_nesting_level++;
+#endif
+
+    elem = first_elem;
+    while (elem < last_elem)
+    {
+#ifdef ERR_TRC_STK_CCD
+      /* 
+       * Save the value for tracing in error case.
+       */
+      globs->error_stack[globs->ccd_recurs_level] = (USHORT) elem;
+#endif /* ERR_TRC_STK_CCD */    
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "encoding level %d element %d", trace_nesting_level, elem - first_elem);
+	#else
+    TRACE_CCD (globs, "encoding level %d element %d '%s'", trace_nesting_level, elem - first_elem ,ccddata_get_alias((USHORT) elem, 1));
+	#endif
+#endif
+
+#if defined _TOOLS_
+      if (!ccd_patch (globs, 0))
+#endif /* _TOOLS_ */
+      /*
+       * Use the jump-table for selecting the code function.
+       * Possible types are 0, ASN1_INTEGER, BITSTRING, ASN1_CHOICE and 
+       * ASN1_SEQUENCE. In case of 0 function cdc_STD_encode will be called.
+       */
+      (void) codec[melem[elem].codingType][ENCODE_FUN]
+                                            (c_ref, elem, globs);
+      /*
+       * Set the elemRef to the next element.
+       */
+      elem ++;
+    }
+#ifdef DEBUG_CCD
+		trace_nesting_level--;
+#endif
+    /*
+     * Set the pointer of the C-structure on the next element.
+     */ 
+    globs->pstruct += cSize;
+
+    repeat ++;
+  }
+
+  /*
+   * Prepare for encoding the next element.
+   */
+  globs->pstruct = old_pstruct;
+  globs->ccd_recurs_level--;
+  return 1;
+}
+#endif /* !RUN_INT_RAM */