diff gsm-fw/ccd/asn1_choice.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_choice.c	Thu Sep 04 05:48:57 2014 +0000
@@ -0,0 +1,320 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  
+|  Modul   : asn1_choice.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_CHOICE
+|             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 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
+const UBYTE bitSize[] = {0, 1, 1, 2, 2, 3, 3, 3, 3,
+            4, 4, 4, 4, 4, 4, 4, 4,
+            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
+#endif /* !RUN_INT_RAM */
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)  MODULE  : asn1_choice                        |
+| STATE   : code        ROUTINE : PER_Decode_ASN1_CHOICE_altervative |
++--------------------------------------------------------------------+
+
+  PURPOSE : Decode a chosen alternative of an ASN.1 CHOICE type
+            Use the parameter union tag bit-size to read the CHOICE
+            index. Because of the ascending enumeration of union tags
+            it is easy to calculate the e_ref for the chosen element 
+            which is to be decoded. Then the appropriate decoding
+            function for the chosen element is called.
+
+            No actions for pointer types (dynamic arrays), as CHOICE
+            clauses contain no information in themselves. Memory is
+            allocated in the containing SEQUENCE instead.
+*/
+void PER_Decode_ASN1_CHOICE_alterative (const ULONG e_ref, T_ENUM UnionTag, T_CCD_Globs *globs)
+{
+  UBYTE *old_pstruct;
+  ULONG elem_ref, c_ref;
+  
+  c_ref = (ULONG) melem[e_ref].elemRef;
+
+  /*
+   * Calculate the elem_ref for the chosen element.
+   * Write the CHOICE tag value in the C-structure.
+   */
+  elem_ref =  mcomp[c_ref].componentRef + (ULONG) UnionTag;
+  *(T_ENUM *) (globs->pstruct+globs->pstructOffs) = (T_ENUM) UnionTag;
+
+  /*
+   * Prepare for decoding next element.
+   * Store the current value of the C-structure pointer. After decoding the CHOICE 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 + sizeof(T_ENUM));
+
+#ifdef DYNAMIC_ARRAYS
+  /*
+   * Allocate memory for this whole composition, if elemType is
+   * one of the pointer types.
+   */
+  if ( is_pointer_type(e_ref) AND
+       PER_allocmem_and_update(e_ref, 1, globs) NEQ ccdOK ) {
+    return;
+  } else
+#endif
+
+  /* 
+   * Call the decode function for the chosen element.
+   */
+  (void) codec[melem[elem_ref].codingType][DECODE_FUN]
+                                        (c_ref, elem_ref, globs);
+  /*
+   * Prepare for decoding the next element.
+   */
+  globs->pstruct = old_pstruct;
+}
+#endif /* !RUN_INT_RAM */
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)              MODULE  : asn1_choice            |
+| STATE   : code                    ROUTINE : cdc_asn1_choice_decode |
++--------------------------------------------------------------------+
+
+  PURPOSE : Decode ASN.1 CHOICE type according to PER
+            CHOICE index is read from the message bit string. Its  
+            bit-size can be extracted from the number of CHOICE
+            alternatives. 
+            For decoding the CHOICE alternative itself, call the same 
+            function as for extensible CHOICE types.
+*/
+SHORT cdc_asn1_choice_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
+{
+  T_ENUM UnionTag=0; /* default: only one alternative */
+  ULONG  num_of_comps, mcomp_ref;
+  
+  mcomp_ref = (ULONG) melem[e_ref].elemRef;
+
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "cdc_asn1_choice_decode()");
+	#else
+	TRACE_CCD (globs, "cdc_asn1_choice_decode() %s", mcomp[mcomp_ref].name);
+	#endif
+#endif
+
+  /* Don't do anything for empty choices */
+  if (mcomp[mcomp_ref].numOfComponents == 0)
+  {
+    return 1;
+  }
+
+  globs->pstructOffs = melem[e_ref].structOffs;
+
+  /* For optional elements we have already set the valid flag in the 
+   * C-structure. We have done it while processing ASN1_SEQ.
+   */
+  if ( ! cdc_isPresent(e_ref, globs) ) {
+    return 1;
+  }
+
+  /* 
+   * Get the bit size of the CHOICE index.
+   * Then read the bits representing the index in the air message.
+   */
+  num_of_comps = (ULONG) mcomp[mcomp_ref].numOfComponents;
+  /* CHOICE index is encoded only if there are more than one alternatives. */
+  if (num_of_comps NEQ 1)
+  {
+    UnionTag = bf_getBits ((U32)bitSize[num_of_comps], globs);
+    /*
+     * Check correctness of the read CHOICE index.
+     */ 
+    if ((ULONG)UnionTag >= num_of_comps)
+    {
+      ccd_recordFault (globs, ERR_ASN1_ENCODING, BREAK, (USHORT) e_ref, globs->pstruct+globs->pstructOffs);
+    }
+  }
+  PER_Decode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs);
+  return 1;
+}
+#endif /* !RUN_INT_RAM */
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)  MODULE  : asn1_choice                        |
+| STATE   : code        ROUTINE : PER_Encode_ASN1_CHOICE_altervative |
++--------------------------------------------------------------------+
+
+  PURPOSE : Encode a chosen alternative of an ASN.1 CHOICE type.
+
+            Because of ascending enumeration of union tags it is
+            easy to calculate the e_ref for the chosen element to be
+						encoded. Then the appropriate encoding function for the 
+            chosen element is called.
+
+            No actions for pointer types (dynamic arrays), as CHOICE
+            clauses contain no information in themselves. Memory is
+            allocated in the containing SEQUENCE instead.
+*/
+void  PER_Encode_ASN1_CHOICE_alterative (const ULONG e_ref, T_ENUM UnionTag, T_CCD_Globs *globs)
+{
+  UBYTE  *old_pstruct;
+  ULONG   elem_ref, c_ref;
+  
+  c_ref = (ULONG) melem[e_ref].elemRef;
+
+  /*
+   * Prepare for encoding next element.
+   * Store the current value of the C-structure pointer. After encoding
+   * the CHOICE 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 + sizeof(T_ENUM));
+
+#ifdef DYNAMIC_ARRAYS
+  /*
+   * Dereference pointer if this is a pointer types (dynamic arrays)
+   * globs->pstruct was saved above, so no need to do it again.
+   */
+  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;
+    }
+  }
+#endif
+
+  elem_ref = mcomp[c_ref].componentRef + (USHORT) UnionTag;
+
+  /* 
+   * Call the decode function for the chosen element.
+   */
+  (void) codec[melem[elem_ref].codingType][ENCODE_FUN]
+                                        (c_ref, elem_ref, globs);
+  /*
+   * Prepare for encoding the next element.
+   */
+  globs->pstruct = old_pstruct;
+}
+#endif /* !RUN_INT_RAM */
+
+#ifndef RUN_INT_RAM
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)              MODULE  : asn1_choice            |
+| STATE   : code                    ROUTINE : cdc_asn1_choice_encode |
++--------------------------------------------------------------------+
+
+  PURPOSE : Encoding of CHOICE type for UMTS
+            The size of the union tag must be calculated. Then its value
+            is written in the air message. 
+						For encoding the CHOICE alternative itself, call the same 
+            function as for extensible CHOICE types. 
+*/
+SHORT cdc_asn1_choice_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
+{
+  T_ENUM UnionTag=0; /* default: only one alternative */
+	ULONG  num_of_comps, mcomp_ref;
+	
+	mcomp_ref = (ULONG) melem[e_ref].elemRef;
+
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "cdc_asn1_choice_encode()");
+	#else
+	TRACE_CCD (globs, "cdc_asn1_choice_encode() %s", mcomp[mcomp_ref].name);
+	#endif
+#endif
+
+  /* Don't do anything for empty choices */
+  if (mcomp[mcomp_ref].numOfComponents == 0)
+  {
+    return 1;
+  }
+
+  globs->pstructOffs = melem[e_ref].structOffs;
+
+  /* For optional elements we have already set the valid flag in the
+   * C-structure. We have done it while processing ASN1_SEQ.
+   */
+  if ( ! cdc_isPresent(e_ref, globs) )
+    return 1;
+
+  /*
+   * Get the value of CHOICE index (= union controller) from the C-structure.
+   * Check its correctness. Write it in the air message.
+	 * Afterwards encode the chosen CHOICE altervative.
+   */
+	num_of_comps = mcomp[mcomp_ref].numOfComponents;
+  /* CHOICE index is encoded only if there are more than one alternatives. */
+  if (num_of_comps NEQ 1)
+  {
+    UnionTag = *(T_ENUM *) (globs->pstruct+globs->pstructOffs);
+    if (UnionTag >= (T_ENUM)num_of_comps)
+    {
+      ccd_recordFault (globs, ERR_ASN1_ENCODING, BREAK, (USHORT) e_ref, 
+                       globs->pstruct+globs->pstructOffs);
+    }
+    bf_writeVal ((ULONG) UnionTag, (ULONG) bitSize[num_of_comps], globs);
+  }
+  PER_Encode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs);
+
+  return 1;
+}
+#endif /* !RUN_INT_RAM */