diff ccd/asn1_integ_ext.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_ext.c	Thu Jun 09 00:02:41 2016 +0000
@@ -0,0 +1,497 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  
+|  Modul   : asn1_integ_ext.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 :  Encoding and decoding functions for ASN1_INTEGER_EXTENSIBLE type
++----------------------------------------------------------------------------- 
+*/ 
+
+/*
+ * 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"
+
+/*
+ * Declaration of coder/decoder tables
+ */
+#include "ccdtable.h"
+#include "ccddata.h"
+
+#ifndef RUN_INT_RAM
+/*
++------------------------------------------------------------------------+
+| PROJECT : CCD (6144)              MODULE  : asn1_integ_ext             |
+| STATE   : code                    ROUTINE : cdc_asn1_integ_ext_decode  |
++------------------------------------------------------------------------+
+
+  PURPOSE : Decode UNALIGNED PER extensible ENUMERATED and INTEGER type 
+            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.
+
+            If the value is in the extension root, it will be encoded as
+            a normally small non-negative whole number. Otherwise it will 
+            be encoded in the smalles number of bits needed to express
+            every enumeration.
+*/
+SHORT cdc_asn1_integ_ext_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
+{
+  ULONG   repeat=1, max_rep=1, var_ref, val_ref;
+  BOOL    DefaultFound= FALSE;
+  S32     IfnotPresent;
+  UBYTE   *value, *old_pstruct = NULL;
+
+  var_ref = (ULONG) melem[e_ref].elemRef;
+
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "cdc_asn1_integ_ext_decode()");
+	#else
+	TRACE_CCD (globs, "cdc_asn1_integ_ext_decode() %s", ccddata_get_alias((USHORT) e_ref, 1));
+	#endif
+#endif
+
+  /* 
+   * For integer with only one possible value in the extension root:
+   * If the extensinon bit is 0, the encoded value is in the extension root.
+   * In this case no arrays are expected.
+   * For other types:
+   * The extension bit and the value will be read in the while-loop below.
+   */
+  if (mvar[var_ref].bSize EQ 0)
+  {
+    if (bf_readBit (globs) EQ FALSE)
+    {
+      Read_unique_Integer (e_ref, globs);
+      return 1;
+    }
+    else
+    {
+      bf_incBitpos (-1, globs);
+    }
+  }
+
+  val_ref = (ULONG) mvar[var_ref].valueDefs;
+  /* 
+   * Set pstrcutOffs and max_rep. Check the valid flag in case of optional elements.
+   */
+  if (PER_CommonBegin (e_ref, &max_rep, 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, max_rep, 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[val_ref+1].isDefault EQ 2)
+  {
+    IfnotPresent = mval[val_ref+1].startValue;
+    DefaultFound = TRUE;
+  }
+
+  /*
+   * Decode all elements of the array.
+   */
+  while ( repeat <= max_rep)
+  {
+
+    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[var_ref].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);
+                  break;
+      }
+    }
+    /* 
+     * 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[val_ref].startValue;
+      ub = mval[val_ref].endValue;
+      /*
+       * Read first the extensinon bit.
+       * Then the non-negative value from the air message.
+       */
+      if (bf_readBit (globs) EQ FALSE)
+      { 
+        readBits = bf_getBits (mvar[var_ref].bSize, globs);
+      }
+      /* Value out of the extension root. */ 
+      else
+      {
+      	U16 calcRef = calcidx[melem[e_ref].calcIdxRef].condCalcRef;
+        /*
+         * Get max value of integer within the extension root.
+         */
+        if (calcRef EQ NO_REF 
+            OR 
+            calc[calcRef].operation NEQ 'P')
+        {
+          ccd_recordFault (globs, ERR_DEFECT_CCDDATA, BREAK, (USHORT)   
+                           e_ref, globs->pstruct+globs->pstructOffs);
+        }
+        else
+        {
+          lb = calc[calcRef].operand;
+        }
+        readBits = Read_NormallySmallNonNegativeWholeNr (globs);
+      }      
+
+
+      if (readBits <= (U32)(ub - lb))
+      {
+        DecodedValue = lb + readBits;
+        /* 
+         * Add the offset to the read value to get the actual one.
+         */
+        switch (mvar[var_ref].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[var_ref].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_ext             |
+| STATE   : code                    ROUTINE : cdc_asn1_integ_ext_encode  |
++------------------------------------------------------------------------+
+
+  PURPOSE : UNALIGNED PER extensible ENUMERATED and INTEGER type 
+            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.
+
+            If the value is in the extension root, it will be encoded as
+            a normally small non-negative whole number. Otherwise it will 
+            be encoded in the smalles number of bits needed to express
+            every enumeration.
+
+			       -----------------------------------------------
+			      | extension  | value encoded as a normally      |
+			      | bit = 1    | non-negtive integer whole number |
+			       -----------------------------------------------
+
+			       -----------------------------------------------
+			      | extension  | value encoded in the bit size    |
+			      | bit = 0    | needed to express ub - lb        |
+			       -----------------------------------------------
+*/
+SHORT cdc_asn1_integ_ext_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
+{
+  ULONG   repeat=1, max_rep=1, var_ref, val_ref;
+  BOOL    DefaultFound= FALSE;
+  S32     IfnotPresent;
+  U8     *base_pstruct;
+
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "cdc_asn1_integ_ext_encode()");
+	#else
+	TRACE_CCD (globs, "cdc_asn1_integ_ext_encode() %s", ccddata_get_alias((USHORT) e_ref, 1));
+	#endif
+#endif
+
+  var_ref = (ULONG) melem[e_ref].elemRef;
+  val_ref = (ULONG) mvar[var_ref].valueDefs;
+
+  /* 
+   * Set pstrcutOffs and max_rep. Check the valid flag in case of optional elements.
+   */
+  if (PER_CommonBegin (e_ref, &max_rep, 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[val_ref+1].isDefault EQ 2)
+  {
+    IfnotPresent = mval[val_ref+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 <= max_rep)
+  {
+    S32     ub, lb, value;
+    U32     extension_lb;
+    UBYTE   *p;
+    U16     calcRef = calcidx[melem[e_ref].calcIdxRef].condCalcRef;
+    /*
+     * Get offset value of integer in the extension addition.
+     */
+    if (calcRef EQ NO_REF 
+        OR 
+        calc[calcRef].operation NEQ 'P')
+    {
+      ccd_recordFault (globs, ERR_DEFECT_CCDDATA, BREAK,(USHORT) e_ref,
+                       globs->pstruct+globs->pstructOffs);
+      return 1;
+    }
+    else
+    {
+      extension_lb = calc[calcRef].operand;
+    }
+    /*
+     * setup the read pointer to the element in the C-structure
+     */
+    p = base_pstruct + globs->pstructOffs;
+
+    switch (mvar[var_ref].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[var_ref].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[var_ref].cType EQ 'L' AND  
+           (mvar[var_ref].bSize EQ 32))
+    {
+      U32 CriticalValue;
+      CriticalValue = *(U32 *) p;
+      if (CriticalValue >= extension_lb)
+      {
+        bf_writeBit (1, globs);
+        if (!DefaultFound OR (U32)IfnotPresent NEQ CriticalValue)
+          Write_NormallySmallNonNegativeWholeNr (CriticalValue - extension_lb, globs);
+      }
+      else
+      {
+        bf_writeBit (0, globs);          
+        if (!DefaultFound OR (U32)IfnotPresent NEQ CriticalValue)
+        {
+          U32 lb, ub;
+          lb = (U32) mval[val_ref].startValue;
+          ub = (U32) mval[val_ref].endValue;
+          if (lb <= CriticalValue && CriticalValue <= ub)
+          {
+            bf_writeVal (CriticalValue - lb, mvar[var_ref].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)
+      {
+        /* 
+         * Set the extension bit to 0 if the value belongs to the extension root.
+         * Otherwise set it to 1.
+         * A non-negative-binary-integer will be encoded since the offset must
+         * be subtracted from the value read from the C-structure.
+         */
+        lb = mval[val_ref].startValue;
+        ub = mval[val_ref].endValue;
+
+        if (value >= (S32)extension_lb AND value <= ub)
+        {
+          bf_writeBit (1, globs);
+          Write_NormallySmallNonNegativeWholeNr ((U32)value - extension_lb, globs);
+        }
+        else if (lb <= value AND value <= ub)
+        {
+          bf_writeBit (0, globs);
+          /* 
+           * Do not encode single valued extension roots.
+           */
+          if (mvar[var_ref].bSize NEQ 0) 
+            bf_writeVal ((ULONG)(value-lb), mvar[var_ref].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);
+        }
+      }
+    } /* value not critical*/
+    repeat ++; 
+    globs->pstructOffs += mvar[var_ref].cSize;
+  }/* while-loop */
+
+  return 1;
+}
+#endif /* !RUN_INT_RAM */