view src/aci2/aci/cmh_mms.c @ 662:8cd8fd15a095

SIM speed enhancement re-enabled and made configurable TI's original code supported SIM speed enhancement, but Openmoko had it disabled, and OM's disabling of speed enhancement somehow caused certain SIM cards to start working which didn't work before (OM's bug #666). Because our FC community is much smaller in year 2020 than OM's community was in their day, we are not able to find one of those #666-affected SIMs, thus the real issue they had encountered remains elusive. Thus our solution is to re-enable SIM speed enhancement and simply wait for if and when someone runs into a #666-affected SIM once again. We provide a SIM_allow_speed_enhancement global variable that allows SIM speed enhancement to be enabled or disabled per session, and an /etc/SIM_spenh file in FFS that allows it to enabled or disabled on a non-volatile basis. SIM speed enhancement is now enabled by default.
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 24 May 2020 05:02:28 +0000
parents 93999a60b835
children
line wrap: on
line source

/* 
+----------------------------------------------------------------------------- 
|  Project :  GSM-PS (6147)
|  Modul   :  CMH_MMS
+----------------------------------------------------------------------------- 
|  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 :  This module provides the set functions related to the
|             protocol stack adapter for mobility management.
+----------------------------------------------------------------------------- 
*/ 

#ifndef CMH_MMS_C
#define CMH_MMS_C
#endif

#include "aci_all.h"

/*==== INCLUDES ===================================================*/
#include "aci_cmh.h"

#include "rtc.h"

#ifdef DTI
#include "dti.h"      /* functionality of the dti library */
#include "dti_conn_mng.h"
#endif

#include "aci_mem.h"

#ifdef FAX_AND_DATA
/* #include "aci_fd.h" */
#endif    /* of #ifdef FAX_AND_DATA */

#include "psa.h"
#include "psa_sim.h"
#include "psa_mm.h"
#include "cmh.h"
#include "cmh_sim.h"
#include "cmh_mm.h"

#include "psa_cc.h"
#include "cmh_cc.h"

#ifdef GPRS
  #include "gaci.h"
  #include "gaci_cmh.h"
  #include "psa_gmm.h"
  #include "cmh_gmm.h"
#endif

#ifndef _SIMULATION_
/***************************/
/* TEMPORARY until NVM     */
/* just to get FFs !!!! */
#ifndef GPRS
#define DONT_LET_FFSH_DEF_GPRS
#endif

#include "ffs/ffs.h"

#include "rx.h"

#include "rtc.h"

#ifdef FF_TIMEZONE
#include "rv/rv_general.h"
#include "rtc/rtc_tz.h"
#endif

/* check whether latter has defined GPRS !!! */
#ifdef DONT_LET_FFSH_DEF_GPRS
#undef GPRS
#endif

#undef DONT_LET_FFSH_DEF_GPRS
/***************************/
#endif /* _SIMULATION_ */


/*==== CONSTANTS ==================================================*/

/*==== EXPORT =====================================================*/

/*==== VARIABLES ==================================================*/

/*==== FUNCTIONS ==================================================*/
EXTERN void wake_up_rr (void);

#ifndef _SIMULATION_
LOCAL void rx_Cb (drv_SignalID_Type *signal_params);
LOCAL UCHAR rx_sequence_Cb (void* arg);
#endif /* _SIMULATION_ */


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PercentBAND          |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %BAND AT command
            which is responsible for configuring the way the mobile
            deals with multiband.

            <bandMode>: band switch mode.
            <bandType>: band selection by user: coded in bitfield as following.            
            Bit set to 1 if band is set, 0 otherwise...
       
     BITS:  |    5   |   4   |    3    |    2    |    1   |      
            | GSM850 | E_GSM | GSM1900 | GSM1800 | GSM900 |
*/

GLOBAL T_ACI_RETURN sAT_PercentBAND(T_ACI_CMD_SRC   srcId,
                                    T_ACI_BAND_MODE bandMode,
                                    UBYTE           bandType)
{
  UBYTE ManufacturerBands;
  UBYTE ubyte_dummy;

  TRACE_FUNCTION("sAT_PercentBAND()");

  /* check command source */
  if(!cmh_IsVldCmdSrc (srcId))
  {
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  /* Check Parameter bandMode */
  switch( bandMode )
  {
  case( BAND_MODE_Auto ):
    bandType = 0x00;    /* scan all */
    break;

  case( BAND_MODE_Manual ):
    /* Check Parameter bandType */
    cmhMM_getBandSettings(&ubyte_dummy, &ManufacturerBands);

    if( !cmhMM_isBandAllowed(bandType, ManufacturerBands) )
    {
      TRACE_EVENT_P1("Band combination %d is not supported by this hardware", bandType);
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
      return( AT_FAIL );
    }
    break;
  
  default:
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  if( !cmhMM_writeSetBand(bandType) )
    return(AT_FAIL);

  /* switch off radio */
  if( CFUNfun EQ CFUN_FUN_Full )
  {
    /* if mobile is on, proceed a soft switch off
     and then switch back on */
    mmEntStat.curCmd = AT_CMD_BAND;

    return( sAT_PlusCFUN( srcId,
                          CFUN_FUN_Disable_TX_RX_RF,
                          CFUN_RST_NotPresent) );
  }
  else
  {
    /* new configuration has been written to Flash and that's it ! */
    return( AT_CMPL);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PlusCOPS             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +COPS AT command
            which is responsible for selection and deselection of an
            network operator.

            <mode>:   registration mode.
            <format>: format of operator selection
            <oper>:   operator string
*/

GLOBAL T_ACI_RETURN sAT_PlusCOPS ( T_ACI_CMD_SRC srcId,
                                   T_ACI_COPS_MOD mode,
                                   T_ACI_COPS_FRMT format,
                                   CHAR * oper )
{

  T_MM_CMD_PRM * pMMCmdPrm;  /* points to MM command parameters */


  T_ACI_NRG_RGMD regMode; /*NRG Registration mode */
  T_ACI_NRG_FRMT regFormat; 
  T_ACI_NRG_SVMD  svrMode;


  TRACE_FUNCTION ("sAT_PlusCOPS()");


  pMMCmdPrm = &cmhPrm[srcId].mmCmdPrm;
  mmShrdPrm.COPSmodeBeforeAbort = mmShrdPrm.COPSmode;
  
/*
  *  check MM entity status
  */
  if( mmEntStat.curCmd NEQ AT_CMD_NONE )

    return( AT_BUSY );


/*
  *convert  format to NRG type and set the COPS format value.
  */


if( format EQ COPS_FRMT_NotPresent ) format = pMMCmdPrm -> COPSfrmt;

  
  switch( format )
  {
    case(    COPS_FRMT_NotPresent): 
    regFormat = NRG_FRMT_NotPresent; 
    break;
    case(   COPS_FRMT_Numeric ): 
    regFormat =NRG_FRMT_Numeric ; 
    break;
    case( COPS_FRMT_Short):
    regFormat = NRG_FRMT_Short; 
    break;
    case( COPS_FRMT_Long):
    regFormat = NRG_FRMT_Long; 
    break;
    default:
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
      return( AT_FAIL );
  }

pMMCmdPrm -> COPSfrmt = format;



/*
  * The function cmhMM_OperatorSelect() is using the NRG types. Therefore the following conversion is required.
  * Also the appropiate value for Service Mode, required by cmhMM_OperatorSelect(),  is set. 
  */


if( mode EQ COPS_MOD_NotPresent ) mode = mmShrdPrm.COPSmode;

switch( mode )
  {
    case( COPS_MOD_NotPresent   ): 
    regMode = NRG_RGMD_NotPresent; 
    svrMode = NRG_SVMD_NotPresent;
    break;
    case(  COPS_MOD_Auto  ): 
    regMode =NRG_RGMD_Auto ; 
    svrMode = NRG_SVMD_Full;    /* Only Full Service makes sense for Automatic Mode */
    break;
    case(  COPS_MOD_Man):
    regMode = NRG_RGMD_Manual; 
    svrMode = NRG_SVMD_Full;   /* Only Full Service makes sense for Manual Mode */ 
    break;
    case(  COPS_MOD_Dereg):
    regMode = NRG_RGMD_Dereg; 
    svrMode = NRG_SVMD_Limited;    
    break;
    case(   COPS_MOD_Both ): 
    regMode = NRG_RGMD_Both; 
    svrMode = NRG_SVMD_Full;  /* Only Full Service makes sense for the Both Mode */
    break;
    case(COPS_MOD_SetOnly):  /*This mode can be fully handled in this function */
       /* DO NOT SET mmShrdPrm.COPSmode !!! */
      pMMCmdPrm -> COPSfrmt = format;
      return AT_CMPL;
    default:
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
      return( AT_FAIL );
  }

mmShrdPrm.COPSmode = mode;



/*Set the value of the current command executed */
mmEntStat.curCmd  = AT_CMD_COPS;  

return cmhMM_OperatorSelect(srcId,regMode,svrMode,regFormat,oper);
  
}


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PercentCOPS             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %COPS AT command
            which is responsible for selection and deselection of an
            network operator. %COPS will add, in principle, 
            the following functionality to the standard AT command +COPS: 
           
            -Possibility to query the "service status" in which the phone is currently registered; 
              the possible values will be "full service", "limited service" or  "no service".
            -Possibility to select the "last registered" operator using  %COPS=1. 


            <mode>:   registration mode.
            <format>: format of operator selection
            <oper>:   operator string
*/

GLOBAL T_ACI_RETURN sAT_PercentCOPS ( T_ACI_CMD_SRC srcId,
                                   T_ACI_COPS_MOD mode,
                                   T_ACI_COPS_FRMT format,
                                   CHAR * oper )
{

  T_MM_CMD_PRM * pMMCmdPrm;  /* points to MM command parameters */


  T_ACI_NRG_RGMD regMode; /*NRG Registration mode */
  T_ACI_NRG_FRMT regFormat; 
  T_ACI_NRG_SVMD  svrMode;


  TRACE_FUNCTION ("sAT_PercentCOPS()");


  pMMCmdPrm = &cmhPrm[srcId].mmCmdPrm;
  mmShrdPrm.COPSmodeBeforeAbort = mmShrdPrm.COPSmode;
  
/*
  *  check MM entity status
  */
  if( mmEntStat.curCmd NEQ AT_CMD_NONE )

    return( AT_BUSY );


/*
 *-------------------------------------------------------------------
 * convert  format to NRG type
 *-------------------------------------------------------------------
 */


if( format EQ COPS_FRMT_NotPresent ) format = pMMCmdPrm -> COPSfrmt;

  
  switch( format )
  {
    case(    COPS_FRMT_NotPresent): 
    regFormat = NRG_FRMT_NotPresent; 
    break;
    case(   COPS_FRMT_Numeric ): 
    regFormat =NRG_FRMT_Numeric ; 
    break;
    case( COPS_FRMT_Short):
    regFormat = NRG_FRMT_Short; 
    break;
    case( COPS_FRMT_Long):
    regFormat = NRG_FRMT_Long; 
    break;
    default:
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
      return( AT_FAIL );
  }

pMMCmdPrm -> COPSfrmt = format;


/*
  * The function cmhMM_OperatorSelect() is using the NRG types. Therefore the following conversion is required.
  * Also the appropiate value for Service Mode, required by cmhMM_OperatorSelect(),  is set. 
  */


if( mode EQ COPS_MOD_NotPresent ) mode = mmShrdPrm.COPSmode;

switch( mode )
  {
    case( COPS_MOD_NotPresent   ): 
    regMode = NRG_RGMD_NotPresent; 
    svrMode = NRG_SVMD_NotPresent;
    break;
    case(  COPS_MOD_Auto  ): 
    regMode =NRG_RGMD_Auto ; 
    svrMode = NRG_SVMD_Full;    
    break;
    case(  COPS_MOD_Man):
    regMode = NRG_RGMD_Manual; 
    svrMode = NRG_SVMD_Full;    
    break;
    case(  COPS_MOD_Dereg):
    regMode = NRG_RGMD_Dereg; 
    svrMode = NRG_SVMD_Limited;    
    break;
    case(   COPS_MOD_Both ): 
    regMode = NRG_RGMD_Both; 
    svrMode = NRG_SVMD_Full; 
    break;
    case(COPS_MOD_SetOnly):  /*This mode can be fully handled in this function */
       /* DO NOT SET mmShrdPrm.COPSmode !!! */
      pMMCmdPrm -> COPSfrmt = format;
      return AT_CMPL;
    default:
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
      return( AT_FAIL );
  }

mmShrdPrm.COPSmode = mode;


  

/* Set the value of the current command executed */
mmEntStat.curCmd  = AT_CMD_P_COPS;  

return cmhMM_OperatorSelect(srcId,regMode,svrMode,regFormat,oper);
  
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PlusWS46             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +WS46 AT
            command which is responsible to select wireless network.

            <mode>: network mode.
*/

GLOBAL T_ACI_RETURN sAT_PlusWS46   (T_ACI_CMD_SRC srcId,
                                    T_ACI_WS46_MOD mode )
{

  TRACE_FUNCTION ("sAT_PlusWS46()");

/*
 *-------------------------------------------------------------------
 * process the value parameter
 *-------------------------------------------------------------------
 */
  if( mode NEQ ACI_NumParmNotPresent )
  {
    if( mode NEQ WS46_MOD_Gsm )
    {
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
      return( AT_FAIL );
    }
  }

  return( AT_CMPL );
}



/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : tAT_PercentALS           |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %ALS AT command
            which is responsible for testing if ALS mode is present.
            (always if an E-Plus Sim-card is detected or the if the CSP
            field is present on the inserted Sim-card and enables
            ALS mode).

            
*/
GLOBAL T_ACI_RETURN tAT_PercentALS  ( T_ACI_CMD_SRC srcId, T_ACI_ALS_MOD *ALSmode )

{ 
  TRACE_FUNCTION ("tAT_PercentALS()");

  if( !cmh_IsVldCmdSrc( srcId ) )
  {
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

#if defined(FF_BAT) && defined(_SIMULATION_)
  /* test command %ALS is not used anymore by BAT.lib, change CMD MODE only for host tests */
  if(aci_cmd_src_mode_get(srcId) EQ CMD_MODE_BAT)
  {
    aci_cmd_src_mode_set((UBYTE)srcId, CMD_MODE_ATI);
  }
#endif /* FF_BAT && _SIMULATION_ */  

  /* E-Plus SIM-Card inserted (mcc=0x262, mnc=0x03) ? */
  if (cmhSIM_plmn_is_hplmn(0x262, 0x03F))
  {
    *ALSmode = ALS_MOD_SPEECH | ALS_MOD_AUX_SPEECH;
    return (AT_CMPL);
  }

  simEntStat.curCmd = AT_CMD_ALS;
  simEntStat.entOwn = simShrdPrm.owner = srcId;

  ccShrdPrm.als_cmd = ALS_CMD_TEST;
  *ALSmode = ALS_MOD_NOTPRESENT;

  cmhCC_checkALS_Support();
  return (AT_EXCT);
}



/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PercentNRG           |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %NRG AT command
            which is responsible for the setting of registration mode
            and service mode.

            <regMode>: registration mode.
            <srvMode>: service mode.
*/

GLOBAL T_ACI_RETURN sAT_PercentNRG( T_ACI_CMD_SRC  srcId,
                                    T_ACI_NRG_RGMD regMode,
                                    T_ACI_NRG_SVMD srvMode,
                                    T_ACI_NRG_FRMT oprFrmt,
                                    CHAR          *opr)
{
  T_MM_CMD_PRM * pMMCmdPrm;  /* points to MM command parameters */

 
  TRACE_FUNCTION ("sAT_PercentNRG()");


  pMMCmdPrm = &cmhPrm[srcId].mmCmdPrm;


/*
 *-------------------------------------------------------------------
 * check MM entity status
 *-------------------------------------------------------------------
 */
  if( mmEntStat.curCmd NEQ AT_CMD_NONE )

    return( AT_BUSY );




 /*
 *-------------------------------------------------------------------
 * process the oprFrmt,svrMode and regMode parameters
 *-------------------------------------------------------------------
 */
  switch( oprFrmt )
  {
    case( NRG_FRMT_NotPresent ):
      oprFrmt = pMMCmdPrm -> NRGoprFrmt;
      break;
    case( NRG_FRMT_Long  ):
    case( NRG_FRMT_Short ):
    case( NRG_FRMT_Numeric ):
      break;
    default:
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
      return( AT_FAIL );
  }   

  if( srvMode EQ NRG_SVMD_NotPresent ) 
    srvMode=pMMCmdPrm->NRGregMode;

  if( regMode EQ NRG_RGMD_NotPresent ) 
    regMode=pMMCmdPrm->NRGregMode;



/* Set the value of the current command executed */
  mmEntStat.curCmd  = AT_CMD_NRG;  


  return cmhMM_OperatorSelect(srcId,regMode,srvMode,oprFrmt,opr);
}

/*
+--------------------------------------------------------------------+
| PROJECT : ACI/MMI                 MODULE  : CMH_MMS                  |
| STATE   : code                    ROUTINE : sAT_PercentCSQ             |
+--------------------------------------------------------------------+

  PURPOSE : This is the function for Signal Quality 
  Param:
  srcId:    command ID;
  CSQmode:  enable(1) or disable(0) CSQ

  Shen,Chao
  Juni.13th, 2003
*/

GLOBAL T_ACI_RETURN sAT_PercentCSQ( T_ACI_CMD_SRC  srcId,
                                    T_ACI_CSQ_MODE CSQmode)
{

  T_MM_CMD_PRM  * pMMCmdPrm;  /* points to MM command parameters */

  if( !cmh_IsVldCmdSrc( srcId ) )
  {
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  pMMCmdPrm = &cmhPrm[srcId].mmCmdPrm;

  switch(CSQmode)
  {
    case( CSQ_Enable):
    {
      if ( pMMCmdPrm->CSQworkStat == CSQ_Enable )
      {
        TRACE_EVENT("CSQ is already enabled");
      }
      else
      {
        cmhPrm[srcId].mmCmdPrm.CSQworkStat = CSQ_Enable;
        if( (pMMCmdPrm->sIndicationParam.sMmCINDSettings.sCindSignalParam <= CIND_SIGNAL_INDICATOR_LVL0) &&
            (pMMCmdPrm->sIndicationParam.sMmCMERSettings.sCmerIndParam != CMER_INDICATOR_2) )
        { /* rx_Init() not yet called from CIND service */
#ifndef _SIMULATION_
          rx_Init(rx_Cb);
#endif /* _SIMULATION_ */
        }
      }
      break;
    }

    case(CSQ_Disable):
    {
      if ( pMMCmdPrm->CSQworkStat == CSQ_Enable )
      {
        cmhPrm[srcId].mmCmdPrm.CSQworkStat = CSQ_Disable;
        if( (pMMCmdPrm->sIndicationParam.sMmCINDSettings.sCindSignalParam <= CIND_SIGNAL_INDICATOR_LVL0) &&
            (pMMCmdPrm->sIndicationParam.sMmCMERSettings.sCmerIndParam != CMER_INDICATOR_2)  )
        { /* CIND service inactive -> no more reading the signal strength necessary */
#ifndef _SIMULATION_
        rx_Init(NULL);
#endif /* _SIMULATION_ */
        }
      }
      break;
    }
    default:
      return(AT_FAIL);
  }
  return( AT_CMPL);
}


/*
+--------------------------------------------------------------------+
| PROJECT : ACI/MMI                 MODULE  : CMH_MMS                |
| STATE   : code                    ROUTINE : sAT_Plus CIND          |
+--------------------------------------------------------------------+

  PURPOSE : This is the function to setup the indications toward
            terminal
*/

GLOBAL T_ACI_RETURN sAT_PlusCIND( T_ACI_CMD_SRC  srcId,
                                       T_ACI_CIND_SIGNAL_TYPE  sCindSgnalSettings,
                                       T_ACI_CIND_SMSFULL_TYPE sCindSmsFullSettings )
{
  T_ACI_MM_CIND_VAL_TYPE  *pMMCindPrm;
  T_ACI_MM_CMER_VAL_TYPE  *pMMCmerPrm;
  T_ACI_CIND_SIGNAL_TYPE   sOldSignalSetting;
  T_ACI_CIND_SMSFULL_TYPE  sOldSmsFullSetting;

  TRACE_EVENT( "sAT_PlusCIND()" );

  if( !cmh_IsVldCmdSrc( srcId ) )
  {
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  pMMCindPrm = &(cmhPrm[srcId].mmCmdPrm.sIndicationParam.sMmCINDSettings);
  pMMCmerPrm = &(cmhPrm[srcId].mmCmdPrm.sIndicationParam.sMmCMERSettings);

  if( sCindSgnalSettings   == CIND_SIGNAL_INDICATOR_INVALID || 
      sCindSmsFullSettings == CIND_SMSFULL_INDICATOR_INVALID )
  {
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  sOldSignalSetting            = pMMCindPrm->sCindSignalParam;
  sOldSmsFullSetting           = pMMCindPrm->sCindSmsFullParam;
  pMMCindPrm->sCindSignalParam  = sCindSgnalSettings;
  pMMCindPrm->sCindSmsFullParam = sCindSmsFullSettings;

  /* ----------------- signal strength setting part ------------------------ */
  if( sOldSignalSetting <= CIND_SIGNAL_INDICATOR_LVL0 )
  { /* the old (previews) signal setting is off */
    if( (sCindSgnalSettings > CIND_SIGNAL_INDICATOR_LVL0) && 
        (cmhPrm[srcId].mmCmdPrm.CSQworkStat == CSQ_Disable) && 
        (pMMCmerPrm->sCmerIndParam != CMER_INDICATOR_2) )
    { /* greather LVL0 --> rx_Init must be initialize... */
#ifndef _SIMULATION_
      rx_Init(rx_Cb);
#endif /* _SIMULATION_ */
    }
  }
  else
  { /* the old (previews) signal setting is on */
    if( (sCindSgnalSettings == CIND_SIGNAL_INDICATOR_LVL0) &&
        (cmhPrm[srcId].mmCmdPrm.CSQworkStat == CSQ_Disable) &&
        (pMMCmerPrm->sCmerIndParam != CMER_INDICATOR_2) )
    { /* LVL0 --> rx_Init must be reset... */
#ifndef _SIMULATION_
        rx_Init(NULL);
#endif /* _SIMULATION_ */
    }
  }
  return(AT_CMPL);
}

/* 
+--------------------------------------------------------------------+
| PROJECT : ACI/MMI                 MODULE  : CMH_MMS                |
| STATE   : code                    ROUTINE : sAT_Plus CMER          |
+--------------------------------------------------------------------+

  PURPOSE : This is the function to setup the buffer control for the 
            indications toward terminal equipment
*/

GLOBAL T_ACI_RETURN sAT_PlusCMER( T_ACI_CMD_SRC  srcId,
                                       T_ACI_CMER_MODE_TYPE sCmerModeSettings,
                                       T_ACI_CMER_IND_TYPE sCmerIndicationSettings,
                                       T_ACI_CMER_BFR_TYPE sCmerBfrSettings )
{
  T_ACI_MM_CMER_VAL_TYPE  *pMMCmerPrm;
  T_ACI_MM_CIND_VAL_TYPE  *pMMCindPrm;
  T_ACI_CMER_IND_TYPE      sOldCmerIndSetting;

  TRACE_EVENT( "sAT_PlusCMER()" );

  if( !cmh_IsVldCmdSrc( srcId ) )
  {
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  pMMCmerPrm = &(cmhPrm[srcId].mmCmdPrm.sIndicationParam.sMmCMERSettings);
  pMMCindPrm = &(cmhPrm[srcId].mmCmdPrm.sIndicationParam.sMmCINDSettings);

  sOldCmerIndSetting        = pMMCmerPrm->sCmerIndParam;
  if( sCmerModeSettings != CMER_MODE_INVALID )
  {
    pMMCmerPrm->sCmerModeParam = sCmerModeSettings;
  }
  if( sCmerIndicationSettings != CMER_INDICATOR_INVALID )
  {
    pMMCmerPrm->sCmerIndParam  = sCmerIndicationSettings;
  }
  if( sCmerBfrSettings != CMER_BFR_INVALID )
  {
    pMMCmerPrm->sCmerBfrParam  = sCmerBfrSettings;
  }

  /* ---------------- maybe switch on all indication settings ------------- */
  if( sOldCmerIndSetting != CMER_INDICATOR_2 )
  { /* the old (previews) indicator setting is 'off' */
    if( (sCmerIndicationSettings == CMER_INDICATOR_2) && 
        (cmhPrm[srcId].mmCmdPrm.CSQworkStat == CSQ_Disable) && 
        (pMMCindPrm->sCindSignalParam <= CIND_SIGNAL_INDICATOR_LVL0) )
    { /* all indications must be show --> rx_Init must be initialize... */
#ifndef _SIMULATION_
      rx_Init(rx_Cb);
#endif /* _SIMULATION_ */
    }
  }
  else
  { /* the old (previews) signal setting is on */
    if( (sCmerIndicationSettings != CMER_INDICATOR_2) &&
        (cmhPrm[srcId].mmCmdPrm.CSQworkStat == CSQ_Disable) &&
        (pMMCindPrm->sCindSignalParam <= CIND_SIGNAL_INDICATOR_LVL0) )
    { /* LVL0 --> rx_Init must be reset... */
#ifndef _SIMULATION_
        rx_Init(NULL);
#endif /* _SIMULATION_ */
    }
  }

  return(AT_CMPL);
}


/*
+--------------------------------------------------------------------+
| PROJECT : ACI/MMI                 MODULE  : CMH_MMS                  |
| STATE   : code                    ROUTINE : sAT_PercentCSQ             |
+--------------------------------------------------------------------+

  PURPOSE : This is the callback function for Signal Quality 
  Param:
  signal_params   callback function name

  Shen,Chao
  Juni.13th, 2003
*/

#ifndef _SIMULATION_
LOCAL void rx_Cb (drv_SignalID_Type *signal_params)
{
    rx_Status_Type *para = NULL;

    TRACE_EVENT("rx_Cb()");

    ACI_MALLOC(para,sizeof(rx_Status_Type));

    para->actLevel = ((rx_Status_Type *) signal_params->UserData)->actLevel;
    para->gsmLevel = ((rx_Status_Type *) signal_params->UserData)->gsmLevel;
    para->rxQuality = ((rx_Status_Type *) signal_params->UserData)->rxQuality;
        
    if (!cmh_set_delayed_call (rx_sequence_Cb, (void *)para))
    {
      TRACE_EVENT("Error, can not set the delayed resequence callback for %CSQ");
      ACI_MFREE(para);
      return ;
    }

    TRACE_EVENT("delayed requence call back requested: 100 ms");
    cmh_start_delayed_call (20);

    return;   
    
}
#endif /* _SIMULATION_ */

/*
+--------------------------------------------------------------------+
| PROJECT : ACI/MMI          MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PercentCSQ             |
+--------------------------------------------------------------------+

  PURPOSE : This is the delayed callback function for Signal Quality 
  Shen,Chao
  Juni.13th, 2003
*/
#ifndef _SIMULATION_
LOCAL UCHAR rx_sequence_Cb (void* arg)
{
  int  i;
  UBYTE rssi;
  UBYTE ber;
  T_ACI_CIND_SIGNAL_TYPE sSignalStrength;
  T_ACI_MM_CIND_VAL_TYPE sIndValues;

  struct rx_Status_Type* tmp_p = (struct rx_Status_Type*) arg;
  
  TRACE_EVENT("rx_sequence_Cb()");

  sIndValues.sCindSmsFullParam = CIND_SMSFULL_INDICATOR_INVALID;

  if ( tmp_p->gsmLevel EQ 0xFF OR tmp_p->gsmLevel EQ 0 )
  {
    rssi = ACI_RSSI_FAULT;
    sSignalStrength = CIND_SIGNAL_INDICATOR_LVL0;
  }
  else if ( tmp_p->gsmLevel > 59 )
  {
    rssi = 31;
  }
  else
  {
    rssi = ( tmp_p->gsmLevel / 2 ) + 2;
  }

  if ( tmp_p->rxQuality EQ RX_QUAL_UNAVAILABLE )
  {
    ber = ACI_BER_FAULT;
  }
  else
  {
    ber = tmp_p->rxQuality;
  }  

  for( i = CMD_SRC_LCL; i < CMD_SRC_MAX; i++)
  {
    if (cmhPrm[i].mmCmdPrm.CSQworkStat EQ CSQ_Enable)
    {
      R_AT (RAT_CSQ, i) (rssi,ber,tmp_p->actLevel);
    }
    /* ==================== process the service of +CIEV ========================== */
    sSignalStrength = CIND_SIGNAL_INDICATOR_LVL0;
    if( tmp_p->gsmLevel >= 11 ) { sSignalStrength = CIND_SIGNAL_INDICATOR_LVL1; };
    if( tmp_p->gsmLevel >= 21 ) { sSignalStrength = CIND_SIGNAL_INDICATOR_LVL2; };
    if( tmp_p->gsmLevel >= 32 ) { sSignalStrength = CIND_SIGNAL_INDICATOR_LVL3; };
    if( tmp_p->gsmLevel >= 42 ) { sSignalStrength = CIND_SIGNAL_INDICATOR_LVL4; };
    if( tmp_p->gsmLevel >= 52 ) { sSignalStrength = CIND_SIGNAL_INDICATOR_LVL5; };
    sIndValues.sCindSignalParam = sSignalStrength;
    sIndValues.sCindSmsFullParam = CIND_SMSFULL_INDICATOR_INVALID;
    if( ((cmhPrm[i].mmCmdPrm.sIndicationParam.sMmCINDSettings.sCindSignalParam > CIND_SIGNAL_INDICATOR_LVL0) &&
         (cmhPrm[i].mmCmdPrm.sIndicationParam.sMmCINDSettings.sCindSignalParam >= sIndValues.sCindSignalParam) &&
          (cmhPrm[i].mmCmdPrm.sIndicationParam.sMmCMERSettings.sCmerIndParam == CMER_INDICATOR_2)) || 
        ((cmhPrm[i].mmCmdPrm.sIndicationParam.sMmCINDSettings.sCindSignalParam < sIndValues.sCindSignalParam) &&
          (cmhPrm[i].mmCmdPrm.sIndicationParam.sMmCMERSettings.sCmerIndParam == CMER_INDICATOR_1)) )
    {
      TRACE_EVENT("send +CIEV");
      R_AT (RAT_CIEV, i) ( sIndValues, cmhPrm[i].mmCmdPrm.sIndicationParam.sMmCMERSettings );
    }
  }

  if (!cmh_set_delayed_call (NULL, NULL))
  { /* reset this callback pointer -> will be set again via rx_Cb */
    TRACE_EVENT("Can not reset the delayed resequence callback for %CSQ");
    return FALSE;
  }
  ACI_MFREE(tmp_p);

  return TRUE;    
}
#endif /* _SIMULATION_ */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PercentCHPL          |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %CHPL AT command
            which will return the list of entries in EF_HPLMNwAcT.

            <mode>:   registration mode.
            <format>: format of operator selection
            <oper>:   operator string
*/

GLOBAL T_ACI_RETURN sAT_PercentCHPL ( T_ACI_CMD_SRC srcId,
                                      T_ACI_OPER_NTRY *oper )
{
  T_OPER_ENTRY   plmnDesc;
  BOOL           found;
  SHORT          mccBuf;
  SHORT          mncBuf;

  TRACE_FUNCTION ("sAT_PlusCHPL()");

/*
 *-------------------------------------------------------------------
 * check whether SIM is ready 
 *-------------------------------------------------------------------
 */
  if (!cmhSMS_checkSIM ())
  {
    return AT_FAIL;
  }

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */
  if(!cmh_IsVldCmdSrc (srcId))
  {
    TRACE_EVENT_P1("sAT_PercentCHPL(): Invalid source: %d", srcId);
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }
  if(!cmhMM_GetActingHPLMN(&mccBuf, &mncBuf))/* Enhancement Acting HPLMN*/
  {
    cmhSIM_GetHomePLMN (&mccBuf, &mncBuf);
  }

  found = cmhMM_FindPLMN (&plmnDesc, mccBuf, mncBuf, NOT_PRESENT_16BIT, FALSE);
  if (!found)
  {
    TRACE_EVENT_P2("sAT_PercentCHPL(): MCC/MN not found in database (0x%X, 0x%X", mccBuf, mncBuf);
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal);
    return( AT_FAIL );
  }

  strcpy (oper->longName, plmnDesc.longName);
  strcpy (oper->shrtName, plmnDesc.shrtName);
  oper->mcc = plmnDesc.mcc;
  oper->mnc = plmnDesc.mnc;
  oper->pnn = plmnDesc.pnn;
  oper->long_len = plmnDesc.long_len;
  oper->shrt_len = plmnDesc.shrt_len;

  return (AT_CMPL);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PlusCTZR             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CTZR AT command
            which will set the status of CTZRmode, indicating whether time
            zone change rep[orting is enabled or disabled.

            <on/off>:   Indicates whether time zone reporting is enabled or disabled.
*/

GLOBAL T_ACI_RETURN sAT_PlusCTZR ( T_ACI_CMD_SRC srcId,
                                   T_ACI_CTZR_MODE mode)
{
  TRACE_FUNCTION ("sAT_PlusCTZR()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */
  if(!cmh_IsVldCmdSrc (srcId))
  {
    TRACE_EVENT_P1("sAT_PlusCTZR(): Invalid source: %d", srcId);
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

/*
 *-------------------------------------------------------------------
 * process the mode parameter
 *-------------------------------------------------------------------
 */
  switch (mode)
  {
    case CTZR_MODE_OFF:
    case CTZR_MODE_ON:
       cmhPrm[srcId].mmCmdPrm.CTZRMode = mode;
       break;

    default:
       TRACE_EVENT_P1("sAT_PlusCTZR(): Invalid mode: %d", mode);
       ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
       return( AT_FAIL );
  }
  
  return( AT_CMPL );
}


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PlusCTZU             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CTZU AT command
            which will set the status of CTZUmode, indicating whether automatic time
            zone update is enabled or disabled.

            <on/off>:   Indicates whether automatic time zone update is enabled or disabled.
*/

GLOBAL T_ACI_RETURN sAT_PlusCTZU ( T_ACI_CMD_SRC srcId,
                                   T_ACI_CTZU_MODE mode)
{
  TRACE_FUNCTION ("sAT_PlusCTZU()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */
  if(!cmh_IsVldCmdSrc (srcId))
  {
    TRACE_EVENT_P1("sAT_PlusCTZU(): Invalid source: %d", srcId);
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

/*
 *-------------------------------------------------------------------
 * process the mode parameter
 *-------------------------------------------------------------------
 */
  switch (mode)
  {
    case CTZU_MODE_OFF:
    case CTZU_MODE_ON:
       cmhPrm[srcId].mmCmdPrm.CTZUMode = mode;
       break;

    default:
       TRACE_EVENT_P1("sAT_PlusCTZU(): Invalid mode: %d", mode);
       ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
       return( AT_FAIL );
  }
  
  return( AT_CMPL );
}


/*
+--------------------------------------------------------------------+
| PROJECT :                       MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PlusCCLK             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CCLK AT command
            which will set the real time clock of the ME
*/

GLOBAL T_ACI_RETURN sAT_PlusCCLK ( T_ACI_CMD_SRC srcId,
                                   T_ACI_RTC_DATE *date_s,
                                   T_ACI_RTC_TIME *time_s,
                                   int timeZone
                                 )
{
#ifndef _SIMULATION_
  UBYTE  ret;
#endif /* _SIMULATION_ */

  TRACE_FUNCTION ("sAT_PlusCCLK()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */
  if(!cmh_IsVldCmdSrc (srcId))
  {
    TRACE_EVENT_P1("sAT_PlusCCLK(): Invalid source: %d", srcId);
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

/*
 *-------------------------------------------------------------------
 * Set the time in the RTC 
 *-------------------------------------------------------------------
 */
#ifndef _SIMULATION_
  ret = rtc_set_time_date( (T_RTC_DATE *) date_s, (T_RTC_TIME *) time_s);

  switch (ret)
  {
    case 0:                     /* RVF_OK. Date and time set ok*/
#ifndef FF_TIMEZONE
      return( AT_CMPL );
#else  /* FF_TIMEZONE */
      ret = RTC_SetCurrentTZ(timeZone); /* Set current timezone now time and date are set.*/
      switch (ret)
      {
        case 0:                /* RVF_OK. RTC current TZ set ok*/
          return( AT_CMPL );

        default:
          TRACE_EVENT_P1("sAT_PlusCCLK(): ERROR1: %d", ret);  /* RTC setting failed */
          return( AT_FAIL );
      }
#endif /* FF_TIMEZONE */

    default:     /* RVF_NOT_READY or RVF_INTERNAL ERROR or RVF_INVALID_PARAMETER */
      TRACE_EVENT_P1("sAT_PlusCCLK(): ERROR2: %d", ret);  /* Date and time setting failed */
      return( AT_FAIL );
  }
#else /* _SIMULATION_ */
  return( AT_CMPL );
#endif /* _SIMULATION_ */

}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PercentCTZV             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %CTZV AT command
            which will set the status of PCTZVmode, indicating whether time and date report
            is enabled or disabled.

            <on/off>:   Indicates whether time and date report is enabled or disabled.
*/

GLOBAL T_ACI_RETURN sAT_PercentCTZV ( T_ACI_CMD_SRC srcId,
                                   T_ACI_PCTZV_MODE mode)
{
  TRACE_FUNCTION ("sAT_PercentCTZV()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */
  if(!cmh_IsVldCmdSrc (srcId))
  {
    TRACE_EVENT_P1("sAT_PercentCTZV(): Invalid source: %d", srcId);
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

/*
 *-------------------------------------------------------------------
 * process the mode parameter
 *-------------------------------------------------------------------
 */
  switch (mode)
  {
    case PCTZV_MODE_OFF:
    case PCTZV_MODE_ON:
       cmhPrm[srcId].mmCmdPrm.PCTZVMode = mode;
       break;

    default:
       TRACE_EVENT_P1("sAT_PercentCTZV(): Invalid mode: %d", mode);
       ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
       return( AT_FAIL );
  }
  
  return( AT_CMPL );
}


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PercentCNIV                |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %CNIV AT command
            which will set the status of CNIVmode, indicating whether time and date report
            is enabled or disabled.

            <on/off>:   Indicates whether time and date report is enabled or disabled.
*/

GLOBAL T_ACI_RETURN sAT_PercentCNIV ( T_ACI_CMD_SRC srcId,
                                   T_ACI_CNIV_MODE mode)
{
  TRACE_FUNCTION ("sAT_PercentCNIV()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */
  if(!cmh_IsVldCmdSrc (srcId))
  {
    TRACE_EVENT_P1("sAT_PercentCNIV(): Invalid source: %d", srcId);
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

/*
 *-------------------------------------------------------------------
 * process the mode parameter
 *-------------------------------------------------------------------
 */
  switch (mode)
  {
    case CNIV_MODE_OFF:
    case CNIV_MODE_ON:
       cmhPrm[srcId].mmCmdPrm.CNIVMode = mode;
       break;

    default:
       TRACE_EVENT_P1("sAT_PercentCNIV(): Invalid mode: %d", mode);
       ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
       return( AT_FAIL );
  }
  
  return( AT_CMPL );
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MMS                  |
| STATE   : code                  ROUTINE : sAT_PercentCWUP          |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CWUP AT command
                   which will force RR to trigger a power campaign.

*/

GLOBAL T_ACI_RETURN sAT_PercentCWUP ( T_ACI_CMD_SRC srcId, T_ACI_CWUP_TYPE type )
{
  TRACE_FUNCTION ("sAT_PercentCWUP()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */
  if(!cmh_IsVldCmdSrc (srcId))
  {
    TRACE_EVENT_P1("sAT_PercentCWUP(): Invalid source: %d", srcId);
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

/*
 *-------------------------------------------------------------------
 * check entity status
 *-------------------------------------------------------------------
 */
  if( mmEntStat.curCmd NEQ AT_CMD_NONE )
  {
    TRACE_EVENT("sAT_PercentCWUP(): MM is busy");    
    return( AT_BUSY );
  }

  wake_up_rr();
  
  return( AT_CMPL );
}


/*==== EOF ========================================================*/