view src/gpf3/ccd/asn1_choice_ext.c @ 600:8f50b202e81f

board preprocessor conditionals: prep for more FC hw in the future This change eliminates the CONFIG_TARGET_FCDEV3B preprocessor symbol and all preprocessor conditionals throughout the code base that tested for it, replacing them with CONFIG_TARGET_FCFAM or CONFIG_TARGET_FCMODEM. These new symbols are specified as follows: CONFIG_TARGET_FCFAM is intended to cover all hardware designs created by Mother Mychaela under the FreeCalypso trademark. This family will include modem products (repackagings of the FCDEV3B, possibly with RFFE or even RF transceiver changes), and also my desired FreeCalypso handset product. CONFIG_TARGET_FCMODEM is intended to cover all FreeCalypso modem products (which will be firmware-compatible with the FCDEV3B if they use TI Rita transceiver, or will require a different fw build if we switch to one of Silabs Aero transceivers), but not the handset product. Right now this CONFIG_TARGET_FCMODEM preprocessor symbol is used to conditionalize everything dealing with MCSI. At the present moment the future of FC hardware evolution is still unknown: it is not known whether we will ever have any beyond-FCDEV3B hardware at all (contingent on uncertain funding), and if we do produce further FC hardware designs, it is not known whether they will retain the same FIC modem core (triband), if we are going to have a quadband design that still retains the classic Rita transceiver, or if we are going to switch to Silabs Aero II or some other transceiver. If we produce a quadband modem that still uses Rita, it will run exactly the same fw as the FCDEV3B thanks to the way we define TSPACT signals for the RF_FAM=12 && CONFIG_TARGET_FCFAM combination, and the current fcdev3b build target will be renamed to fcmodem. OTOH, if that putative quadband modem will be Aero-based, then it will require a different fw build target, the fcdev3b target will stay as it is, and the two targets will both define CONFIG_TARGET_FCFAM and CONFIG_TARGET_FCMODEM, but will have different RF_FAM numbers. But no matter which way we are going to evolve, it is not right to have conditionals on CONFIG_TARGET_FCDEV3B in places like ACI, and the present change clears the way for future evolution.
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 01 Apr 2019 01:05:24 +0000
parents c41a534f33c6
children
line wrap: on
line source

/* 
+----------------------------------------------------------------------------- 
|  Project :  
|  Modul   : asn1_choice_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_CHOICE_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_choice_ext            |
| STATE   : code                    ROUTINE : cdc_asn1_choice_ext_decode |
+------------------------------------------------------------------------+

  PURPOSE : Decode PER extensible CHOICE type 

            The value of the union tag must be calculated from the encoded
            CHOICE index in the air message.
            For CHOICE alternatives within the extension root: the index 
            bit-size relates to max index value in the extension root.
            For CHOICE alternatives within the extension part: the index
            is encoded as a normally small non-negative whole number.

            For decoding the CHOICE alternative itself, call the same 
            function as for non-extensible CHOICE types.
*/
SHORT cdc_asn1_choice_ext_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
{
  U32    extensionBegin;
  T_ENUM UnionTag; /* default: only one alternative */
  ULONG  calc_ref = calcidx[melem[e_ref].calcIdxRef].condCalcRef;

#ifdef DEBUG_CCD
  #ifndef CCD_SYMBOLS
  TRACE_CCD (globs, "cdc_asn1_choice_ext_decode()");
  #else
  TRACE_CCD (globs, "cdc_asn1_choice_ext_decode() %s", mcomp[melem[e_ref].elemRef].name);
  #endif
#endif

  /* Don't do anything for empty choices */
  if (mcomp[melem[e_ref].elemRef].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 max value of CHOICE index within the extension root.
   */
  if (calc_ref EQ NO_REF 
      OR 
      calc[calc_ref].operation NEQ 'P')
  {
    ccd_recordFault (globs, ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, 
                     globs->pstruct+globs->pstructOffs);
    return 1;
  }
  else
  {
    extensionBegin = calc[calc_ref].operand;
  }

  /* 
   * Read the extensinon bit.
   * If set to 1, read the CHOICE index as a normally samll
   * non-negative whole number. Otherwise read it according
   * to the bitSize of index in the extension root.
   */
  if (bf_readBit (globs) EQ 0)
  {
    /* CHOICE index is encoded only if there are more than one alternatives. */
    if (mcomp[melem[e_ref].elemRef].numOfComponents > 1)
    {
      UnionTag = (T_ENUM)bf_getBits (bitSize[extensionBegin], globs);
    }
    else
      UnionTag = 0;

    if (UnionTag >= (T_ENUM)extensionBegin)
    {
      ccd_recordFault (globs, ERR_ASN1_ENCODING, BREAK, (USHORT) e_ref, 
                       globs->pstruct+globs->pstructOffs);
    }
    PER_Decode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs);
  }
  else
  {
    U32 finalBP=0; 
    UnionTag = (T_ENUM)Read_NormallySmallNonNegativeWholeNr (globs);
    UnionTag += extensionBegin;
    finalBP = Read_OpenTpye_Length (globs)*8;
    finalBP += globs->bitpos;

    /*
     * For unknown extension skip over the octets.
     */
    if (UnionTag <= (T_ENUM)mcomp[melem[e_ref].elemRef].numOfComponents)
    {
      PER_Decode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs);
    }
    else
    {
#ifdef DEBUG_CCD
      TRACE_CCD (globs, "Unknown extension with CHOICE index = %ld...skipped to the bit %ld", UnionTag, finalBP);
#endif
    }
    bf_setBitpos (finalBP, globs);
  }

  return 1;
}
#endif /* !RUN_INT_RAM */

#ifndef RUN_INT_RAM
/*
+------------------------------------------------------------------------+
| PROJECT : CCD (6144)              MODULE  : asn1_choice_ext            |
| STATE   : code                    ROUTINE : cdc_asn1_choice_ext_encode |
+------------------------------------------------------------------------+

  PURPOSE : Encode PER extensible CHOICE type
            
      Evaluate the union controller.
      1) It refers to a CHOICE alternative within the extension root:
         Set the extension bit to 0. 
         Write the CHOICE index. 
         Then encode the chosen alternative.
       ------------------------------------
      | extension  | CHOICE  | encoded     |
      | bit        | index   | alternative |
       ------------------------------------

      2) It refers to a CHOICE alternative within the extension list:
        Set the extension bit to 1. 
         Encode the CHOICE index as a normally small non-negative whole nr. 
         Skip over 6 bits dedicated to length determinant.
         Encode the chosen alternative. 
         Calculate the bit size of the encoded alternative.
         Encode the calculated bit size into the field of length 
         determinant. Right shift the encoded alternative, if 6 bits 
         are not enough for the length determinant.
       ------------------------------------------------
      | extension | CHOICE | length      | encoded     |
      | bit       | index  | determinant | alternative |
       ------------------------------------------------

            For encoding the CHOICE alternative itself, call the same 
            function as for non-extensible CHOICE types.
*/
SHORT cdc_asn1_choice_ext_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
{
  U16    startBitpos, Len, EndBitPos;
  T_ENUM UnionTag; /* default: only one alternative */
  U32    extensionBegin;
  ULONG  calc_ref= calcidx[melem[e_ref].calcIdxRef].condCalcRef;

#ifdef DEBUG_CCD
  #ifndef CCD_SYMBOLS
  TRACE_CCD (globs, "cdc_asn1_choice_ext_encode()");
  #else
  TRACE_CCD (globs, "cdc_asn1_choice_ext_encode() %s", mcomp[melem[e_ref].elemRef].name);
  #endif
#endif

  /* Don't do anything for empty choices */
  if (mcomp[melem[e_ref].elemRef].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 max value of CHOICE index within the extension root.
   */
  if (calc_ref EQ NO_REF 
      OR 
      calc[calc_ref].operation NEQ 'P')
  {
    ccd_recordFault (globs, ERR_DEFECT_CCDDATA, BREAK,(USHORT) e_ref, 
                     globs->pstruct+globs->pstructOffs);
    return 1;
  }
  else
  {
    extensionBegin = calc[calc_ref].operand;
  }

  /*
   * Get the value of chosen index (= union controller).
   */
  UnionTag = *(T_ENUM *) (globs->pstruct+globs->pstructOffs);

  /*
   * The chosen alternative belongs to the extension list.
   */
  if ((U32)UnionTag >= extensionBegin)
  {
    /* Encode the extension bit first */
    bf_writeBit (1, globs);
    /* Encode the CHOICE index. */
    Write_NormallySmallNonNegativeWholeNr (((U32)UnionTag - extensionBegin), globs);

    /* Skip over the bits estimated for the length determinant. */
    bf_incBitpos (8, globs);
    startBitpos = globs->bitpos;
    PER_Encode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs);

    /* 
     * Check if zero padding bits are necessary. If encoding 
     * consumed no bits, insert a zero-octet in the bit string.
     * Then calculate length of the encoded open type in octets.
     */
    if ((Len = globs->bitpos - startBitpos) EQ 0)
    {
      bf_writeVal (0, 8, globs);
      Len = 1;
    }
    else 
    {
      if ((Len&7) NEQ 0)
      bf_incBitpos (8 - (Len&7), globs);		  
      Len = (U16)(globs->bitpos - startBitpos) >> 3;
    }
    EndBitPos = globs->bitpos;

    /* 
     * Encode the length determinant.
     */
    if (Len < 128)
    {
      bf_setBitpos (startBitpos-8, globs);
      Write_OpenTpye_Length ((U32)Len, globs);
    }
    /*
     * This case does not seem to happen very often.
     */
    else
    {
      ccd_recordFault (globs, ERR_ASN1_ENCODING, BREAK,(USHORT) e_ref, 
                       globs->pstruct+globs->pstructOffs);
    }
    /* 
     * Encoding for the extensible choice is finished.
     * Set the bit position pointer to the end of encoded open type.
     */
    bf_setBitpos (EndBitPos, globs);
  }
  /*
   * The chosen alternative belongs to the extension root.
   */
  else
  {    
    bf_writeBit (0, globs);
    /* CHOICE index is encoded only if there are more than one alternatives. */
    if (mcomp[melem[e_ref].elemRef].numOfComponents > 1)
    {
      bf_writeVal ((ULONG) UnionTag, (ULONG) bitSize[extensionBegin], globs);
    }
    PER_Encode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs);
  }

  return 1;
}
#endif /* !RUN_INT_RAM */