diff ccd/asn1_integ.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/ccd/asn1_integ.c	Thu Jun 09 00:02:41 2016 +0000
@@ -0,0 +1,512 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  
+|  Modul   : asn1_integ.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_INTEGER
+|             elements 
++----------------------------------------------------------------------------- 
+*/ 
+
+/*
+ * 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 of ccd internal functions
+ */
+#include "ccd.h"
+
+/*
+ * Declaration of coder/decoder tables
+ */
+#include "ccdtable.h"
+#include "ccddata.h"
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)              MODULE  : asn1_integ             |
+| STATE   : code                    ROUTINE : Read_unique_Integer    |
++--------------------------------------------------------------------+
+
+  PURPOSE : Decode integer with only one possible value.
+            Such a value is never encoded.
+*/
+void Read_unique_Integer (const ULONG e_ref, T_CCD_Globs *globs)
+{
+  ULONG  varRef, valRef;
+  U8    *value;
+
+  varRef = (ULONG) melem[e_ref].elemRef;
+  valRef = (ULONG) mvar[varRef].valueDefs;
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "Read_unique_Integer()");
+	#else
+	TRACE_CCD (globs, "Read_unique_Integer() %s", ccddata_get_alias((USHORT) e_ref, 1));
+	#endif
+#endif
+
+  if (mval[valRef].startValue EQ 0)
+  {
+    /* 
+     * Do not do anything for empty sequences and NULL elements.
+     * (Hint: Integers with only one possible value equal to 0 are  
+     * automatically processed through memory reset of the C-structure 
+     * at the beginning of decode activities or after each dynamic
+     * memory allocation.)
+     */
+    return;
+  }
+  else 
+  {
+    /* 
+     * For optional elements we have already set the valid flag in the 
+     * C-structure while processing ASN1_SEQ.
+     */
+    if (melem[e_ref].optional)
+    {
+      if (globs->pstruct[globs->pstructOffs++] EQ FALSE)
+        return;
+    }
+
+#ifdef DYNAMIC_ARRAYS
+    if ( is_pointer_type(e_ref) )
+    {
+	    value = PER_allocmem(e_ref, 1, globs);
+
+	    if (value EQ (U8 *)ccdError)
+	      return;
+
+	    /* 
+       * Store pointer to allocated memory in c structure.
+       */
+	    *(U8 **)(globs->pstruct + globs->pstructOffs) = value;
+    }
+    else
+#endif
+	    value = globs->pstruct + globs->pstructOffs;
+
+    switch (mvar[varRef].cType)
+    {
+      case 'B':
+                *(U8*)  value = (U8)   mval[valRef].startValue;
+                break;
+      case 'C':
+                *(S8*)  value = (S8)   mval[valRef].startValue;
+                break;
+      case 'S':
+                *(U16*) value = (U16)  mval[valRef].startValue;
+                break;
+      case 'T':
+                *(S16*) value = (S16)  mval[valRef].startValue;
+                break;
+      case 'L':
+                *(U32*) value = (U32)  mval[valRef].startValue;
+                break;
+      case 'M':
+                *(S32*) value = (S32)  mval[valRef].startValue;
+                break;
+      default:
+                ccd_recordFault (globs,ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, value);
+                break;
+    }
+    return;
+  }
+}
+#endif /* !RUN_INT_RAM */
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)              MODULE  : asn1_integ             |
+| STATE   : code                    ROUTINE : cdc_asn1_integ_decode  |
++--------------------------------------------------------------------+
+
+  PURPOSE : Encoding of the PER integer type for UMTS
+            PER-visible constraints restrict the integer value to be a
+            constrained whole number. This gives a lower and an upper 
+            bound for the integer. The lb is also called offset. The 
+            encoded value is the difference between the actual and the
+            offset value.
+            A possible and meant default value is never encoded.
+*/
+SHORT cdc_asn1_integ_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
+{
+  ULONG   repeat=1, maxRep=1, varRef, valRef;
+  BOOL    DefaultFound= FALSE;
+  S32     IfnotPresent;
+  UBYTE   *value, *old_pstruct = NULL;
+
+  varRef = (ULONG) melem[e_ref].elemRef;
+ 
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "cdc_asn1_integ_decode()");
+	#else
+	TRACE_CCD (globs, "cdc_asn1_integ_decode() %s", ccddata_get_alias((USHORT) e_ref, 1));
+	#endif
+#endif
+
+  /*
+   * Set the offset in the C-structure on the value for this element.
+   */
+  globs->pstructOffs = melem[e_ref].structOffs;
+
+  /* 
+   * Decode an empty sequence, a NULL element or an integer of constant value.
+   */
+  if (mvar[varRef].bSize EQ 0)
+  {
+    Read_unique_Integer (e_ref, globs);
+    return 1;
+  }
+  valRef = (ULONG) mvar[varRef].valueDefs;
+
+  /* 
+   * Set pstrcutOffs and maxRep. Check the valid flag in case of optional elements.
+   */
+  if (PER_CommonBegin (e_ref, &maxRep, globs) NEQ ccdOK)
+    return 1;
+
+#ifdef DYNAMIC_ARRAYS
+  /*
+   * Allocate memory if this is a pointer type (dynamic array)
+   */
+  if ( is_pointer_type(e_ref) ) {
+    old_pstruct = globs->pstruct;
+    if ( PER_allocmem_and_update(e_ref, maxRep, globs) NEQ ccdOK)
+      /* No memory - Return.  Error already set in function call above. */
+      return 1;
+  }
+#endif
+
+  /* 
+   * Check if there is a default value for the element. 
+   * If yes, just set it aside for a later comparision.  
+   */
+  if (mval[valRef+1].isDefault EQ 2)
+  {
+    IfnotPresent = mval[valRef+1].startValue;
+    DefaultFound = TRUE;
+  }
+
+  /*
+   * Decode all elements of the array.
+   */
+  while ( repeat <= maxRep)
+  {
+
+    value = globs->pstruct + globs->pstructOffs;
+
+    /* 
+     * There is a default value for this integer elment. 
+     * While decoding of the ASN1-SEQUENCE contiaing this integer
+     * we have used a particular byte of C-structure to signalize 
+     * the decoding of a default value (byte set to 0).
+     */
+    if (DefaultFound AND !globs->pstruct[melem[e_ref].structOffs])
+    {
+      switch (mvar[varRef].cType)
+      {
+        case 'B':
+                  *(U8*)  value = (U8)   IfnotPresent;
+                  break;
+        case 'C':
+                  *(S8*)  value = (S8)   IfnotPresent;
+                  break;
+        case 'S':
+                  *(U16*) value = (U16)  IfnotPresent;
+                  break;
+        case 'T':
+                  *(S16*) value = (S16)  IfnotPresent;
+                  break;
+        case 'L':
+                  *(U32*) value = (U32)  IfnotPresent;
+                  break;
+        case 'M':
+                  *(S32*) value = (S32)  IfnotPresent;
+                  break;
+        default:
+                  ccd_recordFault (globs,ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, value);
+                  return 1;
+      }
+    }
+    /* 
+     * There is no default value defined for this integer elment.
+     * Read the value from the bit buffer.
+     */
+    else
+    {
+      U32 ub, lb;
+      ULONG readBits;
+      U32 DecodedValue;
+
+      lb = mval[valRef].startValue;
+      ub = mval[valRef].endValue;
+
+      /*
+       * Read the non-negative value from the air message.
+       */
+      readBits = bf_getBits (mvar[varRef].bSize, globs);
+      
+
+      if (readBits <= (U32)(ub - lb))
+      {
+        DecodedValue = lb + readBits;
+        /* 
+         * Add the offset to the read value to get the actual one.
+
+         */
+        switch (mvar[varRef].cType)
+        {
+          case 'B':
+                    *(U8*)  value = (U8) DecodedValue;
+                    break;
+          case 'C':
+                    *(S8*)  value = (S8) DecodedValue;
+                    break;
+          case 'S':
+                    *(U16*) value = (U16) DecodedValue;
+                    break;
+          case 'T':
+                    *(S16*) value = (S16) DecodedValue;
+                    break;
+          case 'L':
+                    *(U32*) value = (U32) DecodedValue;
+                    break;
+          case 'M':
+                    *(S32*) value = (S32) DecodedValue;
+                    break;
+          default:
+                    ccd_recordFault (globs,ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, value);
+                    break;
+        } 
+      }
+      else
+      {
+#ifdef DEBUG_CCD
+        TRACE_CCD (globs, "integer out of range! %ld require: %ld .. %ld ", DecodedValue, lb, ub);
+#endif
+        if (melem[e_ref].optional)
+          ccd_recordFault (globs, ERR_ASN1_OPT_IE, CONTINUE, (USHORT) e_ref, value);
+        else
+          ccd_recordFault (globs, ERR_ASN1_MAND_IE, CONTINUE, (USHORT) e_ref, value);
+      }
+    }
+    repeat ++;
+    globs->pstructOffs += mvar[varRef].cSize; 
+  }/*while*/
+
+#ifdef DYNAMIC_ARRAYS
+  if (old_pstruct NEQ NULL)
+    globs->pstruct = old_pstruct;
+#endif
+
+  return 1;
+}
+#endif /* !RUN_INT_RAM */
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)              MODULE  : asn1_integ             |
+| STATE   : code                    ROUTINE : cdc_asn1_integ_encode  |
++--------------------------------------------------------------------+
+
+  PURPOSE : Encoding of the PER integer type for UMTS
+            PER-visible constraints restrict the integer value to be a
+            constrained whole number. This gives a lower and an upper 
+            bound for the integer. The lb is also called offset. The 
+            encoded value is the difference between the actual and the
+            offset value. Hence encoded values are non-negative.
+            A possible and meant default value is never encoded. 
+*/
+SHORT cdc_asn1_integ_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
+{
+  ULONG   repeat=1, maxRep=1, varRef, valRef;
+  BOOL    DefaultFound= FALSE;
+  S32     IfnotPresent;
+  U8     *base_pstruct;
+
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "cdc_asn1_integ_encode()");
+	#else
+	TRACE_CCD (globs, "cdc_asn1_integ_encode() %s", ccddata_get_alias((USHORT) e_ref, 1));
+	#endif
+#endif
+
+  varRef = (ULONG) melem[e_ref].elemRef;
+  valRef = (ULONG) mvar[varRef].valueDefs;
+
+  /* 
+   * Don't do anything for empty sequences, NULL elements or integers of constant value.
+   */
+  if (mvar[varRef].bSize EQ 0)
+    return 1;
+
+  /* 
+   * Set pstrcutOffs and maxRep. Check the valid flag in case of optional elements.
+   */
+  if (PER_CommonBegin (e_ref, &maxRep, globs) NEQ ccdOK)
+    return 1;
+
+  /* 
+   * Check if there is a default value for the element. 
+   * If yes, just set it aside for a later comparision.  
+   */
+  if (mval[valRef+1].isDefault EQ 2)
+  {
+    IfnotPresent = mval[valRef+1].startValue;
+    DefaultFound = TRUE;
+  }
+
+#ifdef DYNAMIC_ARRAYS
+  if ( is_pointer_type(e_ref) )
+  {
+    base_pstruct = *(U8 **)(globs->pstruct + globs->pstructOffs);
+    if (ccd_check_pointer(base_pstruct) == ccdOK)
+    {
+      globs->pstructOffs = 0;
+    }
+    else
+    {
+      ccd_recordFault (globs, ERR_INVALID_PTR, BREAK, (USHORT) e_ref, 
+                         &globs->pstruct[globs->pstructOffs]);
+      return 1;
+    }
+  }
+  else
+#endif
+    base_pstruct = globs->pstruct;
+
+  /*
+   * Encode all elements of the array.
+   */
+  while ( repeat <= maxRep)
+  {
+    S32 ub, lb, value;
+    UBYTE   *p;
+
+    /*
+     * setup the read pointer to the element in the C-structure
+     */
+    p = base_pstruct + globs->pstructOffs;
+
+    switch (mvar[varRef].cType)
+    {
+    case 'B':
+      value = (S32)*(UBYTE *) p;
+      break;
+    case 'C':
+      value = (S32)*(S8 *) p;
+      break;
+    case 'S':
+      value = (S32)*(USHORT *) p;
+      break;
+    case 'T':
+      value = (S32)*(S16 *) p;
+      break;
+    case 'L':
+      /* 
+       * This type casting can be critical.
+       * Thus the case of bSize=32 will be handled separately.
+       */
+      if (mvar[varRef].bSize < 32)
+      {
+        value = (S32)*(U32 *) p;
+      }
+      break;
+    case 'M':
+      value = *(S32 *) p;
+      break;
+    default:
+      ccd_recordFault (globs, ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, p);
+      return 1;
+    }
+
+    if (mvar[varRef].cType EQ 'L' AND  
+           (mvar[varRef].bSize EQ 32))
+    {
+        ULONG CriticalValue;
+        U32 lb, ub;
+        CriticalValue = *(U32 *) p;
+        if (!DefaultFound OR (U32)IfnotPresent NEQ CriticalValue)
+        {
+          lb = (U32) mval[valRef].startValue;
+          ub = (U32) mval[valRef].endValue;
+          if (lb <= CriticalValue && CriticalValue <= ub)
+          {
+            bf_writeVal (CriticalValue - lb, mvar[varRef].bSize, globs);
+          }
+        }
+        else
+        {
+#ifdef DEBUG_CCD
+          TRACE_CCD (globs, "integer out of range! %ld require: %ld .. %ld ",
+                             value, lb, ub);
+#endif
+          ccd_recordFault (globs, ERR_INT_VALUE, CONTINUE, (USHORT) e_ref, p);
+        }
+    }
+    else 
+    {
+      /* 
+       * Encode only non-default values.
+       */
+      if (!DefaultFound OR IfnotPresent NEQ value)
+      {
+        /* 
+         * A non-negative-binary-integer will be encoded since the offset must
+         * be subtracted from the value read from the C-structure.
+         */
+        lb = mval[valRef].startValue;
+        ub = mval[valRef].endValue;
+        if (lb <= value AND value <= ub)
+        {
+          bf_writeVal ((ULONG)(value - lb), mvar[varRef].bSize, globs);
+        }
+        else
+        {
+#ifdef DEBUG_CCD
+          TRACE_CCD (globs, "integer out of range! %ld require: %ld .. %ld ", value, lb, ub);
+#endif
+          ccd_recordFault (globs, ERR_INT_VALUE, CONTINUE, (USHORT) e_ref, p);
+        }
+      }
+    }
+    repeat ++; 
+    globs->pstructOffs += mvar[varRef].cSize;
+  }/* while-loop */
+
+  return 1;
+}
+#endif /* !RUN_INT_RAM */