view src/aci2/aci/cmh_mmr.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_MMR
+----------------------------------------------------------------------------- 
|  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 defines the functions which are responsible
|             for the responses of the protocol stack adapter for
|             mobility management.
+----------------------------------------------------------------------------- 
*/ 

#ifndef CMH_MMR_C
#define CMH_MMR_C
#endif

#include "aci_all.h"

/*==== INCLUDES ===================================================*/

#include "aci_cmh.h"
#include "ati_cmd.h"
#include "aci_cmd.h"
#include "aci_mem.h"

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

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

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

#include "cmh_sim.h"

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

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


/*==== TYPES ======================================================*/


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


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

/*==== FUNCTIONS ==================================================*/


/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_MMR                      |
|                            ROUTINE : cmhMM_Registered             |
+-------------------------------------------------------------------+

  PURPOSE : ME is registered to the network

*/

GLOBAL SHORT cmhMM_Registered ( void )
{
  SHORT mncCur, mccCur;   /* holds mnc and mcc of current PLMN */
  UBYTE cmdBuf;           /* buffers current command */

  TRACE_FUNCTION ("cmhMM_Registered()");

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( mmEntStat.curCmd )
  {
    case( AT_CMD_NONE ):
    case( AT_CMD_COPS ):
    case (AT_CMD_P_COPS):
    case( AT_CMD_NRG  ):

      /* check for home PLMN or roaming */
      if( mmShrdPrm.usedPLMN.v_plmn EQ VLD_PLMN  )
      {
        cmhMM_CnvrtPLMN2INT( mmShrdPrm.usedPLMN.mcc,
                             mmShrdPrm.usedPLMN.mnc,
                             &mccCur, &mncCur );

        /* Store the new PLMN and the IMSI in the FFS */
        if (!cmhMM_OperatorStoreInFFS(mmShrdPrm.usedPLMN.mcc,
                                                        mmShrdPrm.usedPLMN.mnc,
                                                        simShrdPrm.imsi.field))
            TRACE_EVENT("Could not write PLMN and IMSI in FFS");                                            
                                                        

        if( cmhSIM_plmn_is_hplmn (mccCur, mncCur))
        {
          cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_Reg);
        }
        else
        {
          cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_Roam);
        }
      }

      if( mmEntStat.curCmd NEQ AT_CMD_NONE )
      {
#if defined (GPRS) AND defined (DTI)
        psaG_MM_CMD_SET_REGMD ( mmShrdPrm.regMode );   /* restore former registration mode*/
#else
        /* restore former registration mode */
        psaMM_SetRegMode ( mmShrdPrm.regMode );
#endif

        cmdBuf = mmEntStat.curCmd;
        mmEntStat.curCmd = AT_CMD_NONE;

        R_AT( RAT_OK, mmEntStat.entOwn )
          ( cmdBuf );

        /* log result */
        cmh_logRslt ( mmEntStat.entOwn, RAT_OK, cmdBuf, -1, -1, -1 );
      }



      break;
  }

  return 0;
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_MMR                      |
|                            ROUTINE : cmhMM_Deregistered           |
+-------------------------------------------------------------------+
	
  PURPOSE : ME is deregistered from network

*/

GLOBAL SHORT cmhMM_Deregistered ( void )
{
  T_ACI_RETURN ret;

  TRACE_FUNCTION ("cmhMM_Deregistered()");

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( mmEntStat.curCmd )
  {
    case( AT_CMD_NONE ):
   /*
    *----------------------------------------------------------------
    * process event if no command was invoked
    *----------------------------------------------------------------
    */
      switch( mmShrdPrm.deregCs )
      {
        case( NREG_LIMITED_SERVICE ):
        case( NREG_NO_SERVICE ):

          if (mmShrdPrm.regModeAutoBack)
          {
            /*
             * Fallback to automatic mode is allowed, fallback.
             * If MM is not in full service and the registration mode
             * is switched from manual to automatic,
             * MM starts a network search immediately.
             */
            mmShrdPrm.regModeBeforeAbort = mmShrdPrm.regMode;
            mmShrdPrm.regMode = MODE_AUTO;
            mmShrdPrm.regModeAutoBack = FALSE;
#if defined (GPRS) AND defined (DTI)
            psaG_MM_CMD_SET_REGMD ( MODE_AUTO );
#else
            psaMM_SetRegMode (MODE_AUTO);
#endif
          }

          cmhMM_Ntfy_NtwRegistrationStatus(cmhMM_GetNregCREGStat());
          break;
      }
      break;

    case( AT_CMD_CFUN ):
   /*
    *----------------------------------------------------------------
    * process event for +CFUN command
    *----------------------------------------------------------------
    */
      mmEntStat.curCmd = AT_CMD_NONE;

      cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_NoSearch);

      if (simEntStat.curCmd NEQ AT_CMD_CFUN)     /* Has SIM already finished flushing of LDN entries? */
      {
        R_AT( RAT_OK, mmEntStat.entOwn )
          ( AT_CMD_CFUN );

        /* log result */
        cmh_logRslt ( mmEntStat.entOwn, RAT_OK, AT_CMD_CFUN, -1, -1, -1 );
      }

      break;

    case( AT_CMD_BAND ):
   /*
    *----------------------------------------------------------------
    * process event for %BAND command
    *----------------------------------------------------------------
    */
      cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_NoSearch);

      /* switch back to full functionnality */
      ret = sAT_PlusCFUN( mmEntStat.entOwn,
                          CFUN_FUN_Full,
                          CFUN_RST_NotPresent );


     /* SPR#919 - SH - fix advised by CLB */
     mmEntStat.curCmd = AT_CMD_NONE;
      simEntStat.curCmd = AT_CMD_NONE;
      /* end SH */
      
      if( ret EQ AT_CMPL )
      {
        R_AT( RAT_OK, mmEntStat.entOwn )
                (AT_CMD_BAND);
      }
      else
      {
        TRACE_EVENT_P1
            ("Fatal Error in sAT_PlusCFUN switching on !!!, ret_type: %d", ret);
        R_AT( RAT_CME, mmEntStat.entOwn )
                        ( AT_CMD_BAND, CME_ERR_Unknown );
        
      }
      /*SPR#919 - SH - fix advised by CLB
      mmEntStat.curCmd = AT_CMD_NONE;
      simEntStat.curCmd = AT_CMD_NONE;
      */
      break;

    case( AT_CMD_COPS ):
    case( AT_CMD_P_COPS):
      /*
       *----------------------------------------------------------------
       * process event for +COPS command
       *----------------------------------------------------------------
       */
      switch( mmShrdPrm.COPSmode )
      {
        case( COPS_MOD_Auto   ):
        case( COPS_MOD_Man   ):

          mmEntStat.curCmd = AT_CMD_NONE;

          cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_Denied);

#if defined (GPRS) AND defined (DTI)
          psaG_MM_CMD_SET_REGMD ( mmShrdPrm.regMode );   /* restore former registration mode*/
#else
          /* restore former registration mode */
          psaMM_SetRegMode ( mmShrdPrm.regMode);
#endif

          R_AT( RAT_CME, mmEntStat.entOwn )
            ( mmEntStat.curCmd, cmhMM_GetNregCMEStat() );

          /* log result */
          cmh_logRslt ( mmEntStat.entOwn, RAT_CME, AT_CMD_COPS, -1, -1,
            cmhMM_GetNregCMEStat() );
          break;

        case( COPS_MOD_Dereg   ):

          cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_NoSearch);

          R_AT( RAT_OK, mmEntStat.entOwn )
            ( mmEntStat.curCmd );

          /* log result */
          cmh_logRslt ( mmEntStat.entOwn, RAT_OK, mmEntStat.curCmd, -1, -1, -1 );

          mmEntStat.curCmd = AT_CMD_NONE;
          break;

        case( COPS_MOD_SetOnly   ):

          cmhMM_Ntfy_NtwRegistrationStatus(cmhMM_GetNregCREGStat());
          break;

        case( COPS_MOD_Both   ):

          if (mmShrdPrm.regModeAutoBack)
          {
            /*
             * Tried register to network in manual mode. Attempt failed.
             * Now trying to register into network in automatic mode.
             */
            mmShrdPrm.regModeBeforeAbort = mmShrdPrm.regMode;
            mmShrdPrm.regMode = MODE_AUTO;
            mmShrdPrm.regModeAutoBack = FALSE;

#if defined (GPRS) AND defined (DTI)
            if( psaG_MM_CMD_REG ( ) < 0 )  /* register to network */
#else
            if( psaMM_Registrate () < 0 )  /* register to network */
#endif
            {
              TRACE_EVENT( "FATAL RETURN psaMM_Registrate in +COPS" );

              R_AT( RAT_CME, mmEntStat.entOwn )
                ( mmEntStat.curCmd, cmhMM_GetNregCMEStat());

              /* log result */
              cmh_logRslt ( mmEntStat.entOwn, RAT_CME, mmEntStat.curCmd, -1, -1,
                            cmhMM_GetNregCMEStat() );

              mmEntStat.curCmd = AT_CMD_NONE;
            }
          }
          else
          {
            cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_Denied);

#if defined (GPRS) AND defined (DTI)
            psaG_MM_CMD_SET_REGMD ( mmShrdPrm.regMode );   /* restore former registration mode*/
#else
            /* restore former registration mode or set new one */
            psaMM_SetRegMode ( mmShrdPrm.regMode );
#endif

            R_AT( RAT_CME, mmEntStat.entOwn )
                ( mmEntStat.curCmd, cmhMM_GetNregCMEStat() );

            /* log result */
            cmh_logRslt ( mmEntStat.entOwn, RAT_CME, mmEntStat.curCmd, -1, -1,
                          cmhMM_GetNregCMEStat() );

            mmEntStat.curCmd = AT_CMD_NONE;
          }
          break;
      }
      break;

    case( AT_CMD_NRG ):
   /*
    *----------------------------------------------------------------
    * process event for %NRG command
    *----------------------------------------------------------------
    */
    switch( cmhPrm[mmEntStat.entOwn].mmCmdPrm.NRGsrvMode )
    {
    case( NRG_SVMD_Full    ):

      switch( cmhPrm[mmEntStat.entOwn].mmCmdPrm.NRGregMode )
      {
      case( NRG_RGMD_Auto   ):
      case( NRG_RGMD_Manual ):

        mmEntStat.curCmd = AT_CMD_NONE;

        cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_Denied);

#if defined (GPRS) AND defined (DTI)
        psaG_MM_CMD_SET_REGMD ( mmShrdPrm.regMode );   /* restore former registration mode*/
#else
        /* restore former registration mode */
        psaMM_SetRegMode ( mmShrdPrm.regMode );
#endif

        R_AT( RAT_CME, mmEntStat.entOwn )
          ( AT_CMD_NRG, cmhMM_GetNregCMEStat());

        /* log result */
        cmh_logRslt ( mmEntStat.entOwn, RAT_CME, AT_CMD_NRG, -1, -1,
                      cmhMM_GetNregCMEStat() );
        break;

      case( NRG_RGMD_Both ):
        if (mmShrdPrm.regModeAutoBack)
        {
          /*
           * Tried register to network in manual mode. Attempt failed.
           * Now trying to register into network in automatic mode.
           */
          mmShrdPrm.regModeBeforeAbort = mmShrdPrm.regMode; 
          mmShrdPrm.regMode = MODE_AUTO;
          mmShrdPrm.regModeAutoBack = FALSE;

#if defined (GPRS) AND defined (DTI)
          if( psaG_MM_CMD_REG ( ) < 0 )  /* register to network */
#else
          if( psaMM_Registrate () < 0 )  /* register to network */
#endif
          {
            mmEntStat.curCmd = AT_CMD_NONE;
            TRACE_EVENT( "FATAL RETURN psaMM_Registrate in %NRG" );

            R_AT( RAT_CME, mmEntStat.entOwn )
              ( AT_CMD_NRG, cmhMM_GetNregCMEStat());

            /* log result */
            cmh_logRslt ( mmEntStat.entOwn, RAT_CME, AT_CMD_NRG, -1, -1,
                          cmhMM_GetNregCMEStat() );
          }
        }
        else
        {
          mmEntStat.curCmd = AT_CMD_NONE;

          cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_Denied);

          /* If fallback to automatic mode is allowed, fall back */
          if (mmShrdPrm.regModeAutoBack)
          {
            mmShrdPrm.regModeBeforeAbort = mmShrdPrm.regMode;
            mmShrdPrm.regModeAutoBack = FALSE;
            mmShrdPrm.regMode = MODE_AUTO;
          }

#if defined (GPRS) AND defined (DTI)
          psaG_MM_CMD_SET_REGMD ( mmShrdPrm.regMode );   /* restore former registration mode*/
#else
          /* restore former registration mode or set new one */
          psaMM_SetRegMode ( mmShrdPrm.regMode );
#endif

          R_AT( RAT_CME, mmEntStat.entOwn )
              ( AT_CMD_NRG, cmhMM_GetNregCMEStat() );

          /* log result */
          cmh_logRslt ( mmEntStat.entOwn, RAT_CME, AT_CMD_NRG, -1, -1,
                        cmhMM_GetNregCMEStat() );
        }
        break;
      }
      break;

    case( NRG_SVMD_Limited ):

      /* pending registration request */
      if( regReqPnd EQ TRUE )
      {
        mmShrdPrm.regMode = MODE_AUTO;

#if defined (GPRS) AND defined (DTI)
        (void)psaG_MM_CMD_REG ();  /* register to network */
#else
        (void)psaMM_Registrate (); /* register to network */
#endif

        regReqPnd = FALSE;
        break;
      }

      if( mmShrdPrm.regStat EQ RS_LMTD_SRV )
      {
        mmEntStat.curCmd = AT_CMD_NONE;

        cmhMM_Ntfy_NtwRegistrationStatus(cmhMM_GetNregCREGStat());

        R_AT( RAT_OK, mmEntStat.entOwn )
          ( AT_CMD_NRG );

        /* log result */
        cmh_logRslt ( mmEntStat.entOwn, RAT_OK, AT_CMD_NRG, -1, -1, -1 );
      }
      else
      {
        mmEntStat.curCmd = AT_CMD_NONE;

        cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_Denied);

#if defined (GPRS) AND defined (DTI)
        psaG_MM_CMD_SET_REGMD ( mmShrdPrm.regMode );   /* restore former registration mode*/
#else
        /* restore former registration mode */
        psaMM_SetRegMode ( mmShrdPrm.regMode );
#endif

        R_AT( RAT_CME, mmEntStat.entOwn )
          ( AT_CMD_NRG, cmhMM_GetNregCMEStat() );

        /* log result */
        cmh_logRslt ( mmEntStat.entOwn, RAT_CME, AT_CMD_NRG, -1, -1,
                      cmhMM_GetNregCMEStat() );
      }
      break;

    case( NRG_SVMD_NoSrv   ):

      mmEntStat.curCmd = AT_CMD_NONE;

      cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_NoSearch);

      R_AT( RAT_OK, mmEntStat.entOwn )
        ( AT_CMD_NRG );

      /* log result */
      cmh_logRslt ( mmEntStat.entOwn, RAT_OK, AT_CMD_NRG, -1, -1, -1 );
      break;

    case( NRG_SVMD_SetRegModeOnly ):

      cmhMM_Ntfy_NtwRegistrationStatus(cmhMM_GetNregCREGStat());
      break;

    }
    break;
  }

  return 0;
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_MMR                      |
|                            ROUTINE : cmhMM_NetworkLst             |
+-------------------------------------------------------------------+

  PURPOSE : List of networks available

*/

GLOBAL SHORT cmhMM_NetworkLst ( void )
{
  /* 
   * We need a structure which has to fit into one not too big partition.
   * sizeof (T_OP_NAME) = 36 (35 characters plus one alignment byte)
   * with MAX_LONG_OPER_LEN = 26 and MAX_SHRT_OPER_LEN = 9
   * => sizeof (T_OP_NAME) * MAX_OPER = 432
   * => This fits into one of the 432er partitions of which we have some.
   */
  typedef struct
  {
    char longNamBuf[MAX_LONG_OPER_LEN]; /* buffer long name */
    char shrtNamBuf[MAX_SHRT_OPER_LEN]; /* buffer short name*/
  } T_OP_NAME;

  T_OP_NAME    * op_name = NULL;      /* Holds operator names */
  T_OPER_ENTRY   plmnDesc;            /* PLMN description */
  T_ACI_COPS_OPDESC * operLst = NULL; /* operator list T_ACI_COPS_LST */
  SHORT          lstIdx;              /* holds list idx */
  SHORT          mcc, mnc;            /* holds converted mnc and mcc */
  BOOL           found;               /* Result of cmhMM_FindXXX() */
  T_ACI_AT_CMD   bufCmd;

  TRACE_FUNCTION ("cmhMM_NetworkLst()");

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( mmEntStat.curCmd )
  {
    case( AT_CMD_COPS ):
    case (AT_CMD_P_COPS):

    ACI_MALLOC (op_name, sizeof (T_OP_NAME) * MAX_OPER);
    ACI_MALLOC (operLst, sizeof (T_ACI_COPS_OPDESC) * MAX_OPER);

    /*
     *---------------------------------------------------------------
     * for every entry of the PLMN list
     *---------------------------------------------------------------
     */
    for( lstIdx = 0; lstIdx < MAX_OPER AND lstIdx < MAX_PLMN_ID; lstIdx++ )
    {
      /*
       *-------------------------------------------------------------
       * if last entry of PLMN list, close oper list and return
       *-------------------------------------------------------------
       */
      if( mmShrdPrm.PLMNLst[lstIdx].v_plmn EQ INVLD_PLMN )
      {
        operLst[lstIdx].status    = COPS_STAT_NotPresent;
        operLst[lstIdx].longOper  = NULL;
        operLst[lstIdx].shortOper = NULL;
        operLst[lstIdx].numOper[0]= '\0';
        break;
      }

      /*
       *-------------------------------------------------------------
       * find PLMN description
       *-------------------------------------------------------------
       */
      cmhMM_CnvrtPLMN2INT( mmShrdPrm.PLMNLst[lstIdx].mcc,
                           mmShrdPrm.PLMNLst[lstIdx].mnc,
                           &mcc, &mnc );

      found = cmhMM_FindPLMN (&plmnDesc, mcc, mnc, mmShrdPrm.LACLst[lstIdx], TRUE);

      if (!found)  /* no description found */
      {
        operLst[lstIdx].longOper  =  "";
        operLst[lstIdx].shortOper =  ""; 
      }
      else
      {
        /* Copy strings into dynamic buffer so that they don't get lost */
        memcpy (op_name[lstIdx].longNamBuf, plmnDesc.longName, MAX_LONG_OPER_LEN);
        memcpy (op_name[lstIdx].shrtNamBuf, plmnDesc.shrtName, MAX_SHRT_OPER_LEN);

        /* EONS PLMN name conding scheme and source flag */
        operLst[lstIdx].pnn          = plmnDesc.pnn;
        operLst[lstIdx].longOper     = op_name[lstIdx].longNamBuf;
        operLst[lstIdx].long_len     = plmnDesc.long_len;
        operLst[lstIdx].long_ext_dcs = plmnDesc.long_ext_dcs;
        operLst[lstIdx].shortOper    = op_name[lstIdx].shrtNamBuf;
        operLst[lstIdx].shrt_len     = plmnDesc.shrt_len;
        operLst[lstIdx].shrt_ext_dcs = plmnDesc.shrt_ext_dcs;
      }

      /*
       *-------------------------------------------------------------
       * build numeric representation
       *-------------------------------------------------------------
       */
      if ((mnc & 0x00F) EQ 0x00F)
        sprintf (operLst[lstIdx].numOper, "%03X%02X", mcc, (mnc & 0xFF0) >> 4);
      else
        sprintf (operLst[lstIdx].numOper, "%03X%03X", mcc, mnc);

      /*
       *-------------------------------------------------------------
       * set PLMN status
       *-------------------------------------------------------------
       */
      if (mmShrdPrm.PLMNLst[lstIdx].v_plmn EQ mmShrdPrm.usedPLMN.v_plmn AND
          memcmp (mmShrdPrm.PLMNLst[lstIdx].mcc,
                  mmShrdPrm.usedPLMN.mcc, 
                  SIZE_MCC) EQ 0 AND
          memcmp (mmShrdPrm.PLMNLst[lstIdx].mnc, 
                  mmShrdPrm.usedPLMN.mnc, SIZE_MNC) EQ 0)
      {
        operLst[lstIdx].status = COPS_STAT_Current;
      }
      else
      {
        switch( mmShrdPrm.FRBLst[lstIdx] )
        {
          case( FORB_PLMN_NOT_INCLUDED ):
            operLst[lstIdx].status = COPS_STAT_Available;
            break;
          case( 1 /*FORB_PLMN_INCLUDED*/ ):
            operLst[lstIdx].status = COPS_STAT_Forbidden;
            break;
          default:
            operLst[lstIdx].status = COPS_STAT_Unknown;
            break;
        }
      }
    }

#if defined (GPRS) AND defined (DTI)
    psaG_MM_CMD_SET_REGMD ( mmShrdPrm.regMode );   /* restore former registration mode*/
#else
    /* restore former registration mode */
    psaMM_SetRegMode ( mmShrdPrm.regMode );
#endif
    bufCmd = mmEntStat.curCmd;
    mmEntStat.curCmd = AT_CMD_NONE;
    if(bufCmd EQ AT_CMD_COPS)
    {
      R_AT( RAT_COPS, mmEntStat.entOwn )
      ( --lstIdx, &operLst[0]);
    }
    else
    {
      R_AT( RAT_P_COPS, mmEntStat.entOwn )
      ( --lstIdx, &operLst[0]);
    }
    R_AT( RAT_OK, mmEntStat.entOwn )
      ( mmEntStat.curCmd );

    /* log result */
    cmh_logRslt ( mmEntStat.entOwn, RAT_OK, mmEntStat.curCmd , -1, -1, -1 );

    ACI_MFREE (op_name);
    ACI_MFREE (operLst);

    break;
  }

  return 0;
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_MMR                      |
|                            ROUTINE : cmhMM_SelNetwork             |
+-------------------------------------------------------------------+

  PURPOSE : Select a network

*/

GLOBAL SHORT cmhMM_SelNetwork ( void )
{
  TRACE_FUNCTION ("cmhMM_SelNetwork()");

  switch( mmEntStat.curCmd )
  {
    case( AT_CMD_COPS ):

#if defined (GPRS) AND defined (DTI)
      psaG_MM_CMD_SET_REGMD ( mmShrdPrm.regMode );   /* restore former registration mode*/
#else
      /* restore former registration mode */
      psaMM_SetRegMode ( mmShrdPrm.regMode );
#endif

      /* If the SIM is not inserted or if the SIM requires a PIN, more meaningful error 
       * codes are returned*/
      if ( (cmhSIM_GetSIMError(mmEntStat.entOwn, mmEntStat.curCmd)) NEQ AT_CMPL)
      {
        R_AT( RAT_CME, mmEntStat.entOwn ) ( mmEntStat.curCmd , CME_ERR_NotPresent);
      }

      /* log result */
      cmh_logRslt ( mmEntStat.entOwn, RAT_CME, mmEntStat.curCmd , -1, -1, CME_ERR_NotPresent );

      mmEntStat.curCmd = AT_CMD_NONE;

      break;
  }

  return 0;
}


/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_MMR                      |
|                            ROUTINE : cmhMM_CipheringInd           |
+-------------------------------------------------------------------+

  PURPOSE : ciphering indication received

*/

GLOBAL SHORT cmhMM_CipheringInd ( UBYTE ciph )
{
  SHORT idx;                  /* holds index counter */

  TRACE_FUNCTION ("cmhMM_CipheringInd()");

  if (simShrdPrm.ciSIMEnabled NEQ TRUE)
  {
    return 1;
  }

  for (idx = 0; idx < CMD_SRC_MAX; idx++)
  {
     /*
     *-----------------------------------------------------------------
     * new message indication
     *-----------------------------------------------------------------
     */
#ifndef GPRS
  #define CIPH_NA 2
#endif
     R_AT(RAT_P_CPRI,idx) ( ciph, CIPH_NA );
  }
  return 0;
}


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