FreeCalypso > hg > fc-magnetite
view src/g23m-aci/aci/cmh_simf.c @ 199:78d46b5cda38
configs/hybrid: recipe created
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 14 Oct 2016 01:42:52 +0000 |
parents | 53929b40109c |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : GSM-PS (6147) | Modul : CMH_SIMF +----------------------------------------------------------------------------- | 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 used by the commad | handler for the subscriber identity module. +----------------------------------------------------------------------------- */ #ifndef CMH_SIMF_C #define CMH_SIMF_C #endif #include "aci_all.h" /*==== INCLUDES ===================================================*/ #include "aci_cmh.h" #include "ati_cmd.h" #include "aci_cmd.h" #include "pcm.h" #ifdef DTI #include "dti.h" #include "dti_conn_mng.h" #endif #ifdef FAX_AND_DATA #include "aci_fd.h" #endif /* of #ifdef FAX_AND_DATA */ #include "aci.h" #include "psa.h" #include "psa_sim.h" #include "psa_cc.h" #include "psa_sat.h" #include "psa_mm.h" #include "psa_util.h" #include "cmh.h" #include "cmh_sim.h" #include "cmh_mm.h" #include "phb.h" #include "cmh_phb.h" #ifdef TI_PS_OP_OPN_TAB_ROMBASED #include "plmn_decoder.h" #include "rom_tables.h" #endif #ifdef SIM_PERS #include "aci_ext_pers.h" #include "aci_slock.h" #include "general.h" /* inluded for UINT8 compilation error in sec_drv.h */ #include "sec_drv.h" EXTERN T_ACI_SIM_CONFIG aci_slock_sim_config; EXTERN T_SEC_DRV_CONFIGURATION *cfg_data; #endif /* #include "m_cc.h" */ /*==== CONSTANTS ==================================================*/ /*==== TYPES ======================================================*/ /*==== EXPORT =====================================================*/ /*==== VARIABLES ==================================================*/ const UBYTE PLMNselEmpty[] = { 0xFF, 0xFF, 0xFF }; #ifdef SIM_PERS_OTA UBYTE nw_ctrl_key[9], nw_subset_ctrl_key[9], sp_ctrl_key[9], corp_ctrl_key[9]; #define MAX_DCK_LEN 16 #endif /* Implements Measure#32: Row 60 & 1039 */ const char * const ef_mssup_id = EF_MSSUP_ID; /*==== FUNCTIONS ==================================================*/ void cmhSIM_Read_AD_cb(SHORT table_id); void cmhSIM_Get_CSP_cb(SHORT table_id); void cmhSIM_Read_CSP_cb(SHORT table_id); #ifdef SIM_PERS_OTA void cmhSIM_Read_DCK_cb(SHORT table_id); void cmhSIM_Read_DCK_init_cb(SHORT table_id); void cmhSIM_WriteDefaultValue_DCK_cb(SHORT table_id); #endif LOCAL void cmhSIM_OpRead_simDataFld_RcdCb( SHORT table_id, USHORT reqDataFld ); LOCAL BOOL cmhSIM_AD_CSP_Update ( int ref, T_SIM_FILE_UPDATE_IND *fu, USHORT sim_datafld ); LOCAL BOOL cmhSIM_OpRead_Opl_or_Pnn_Rcd( UBYTE rcd, USHORT reqDataFld, void (*rplyCB)(SHORT) ); LOCAL T_ACI_RETURN cmhSIM_Write_or_Read_TranspEF ( T_ACI_CMD_SRC srcId, T_ACI_AT_CMD cmd, USHORT datafield, USHORT offset, UBYTE datalen, UBYTE * exchData, void (*rplyCB)(SHORT), T_SIM_ACTP accType, BOOL v_path_info, T_path_info *path_info_ptr); LOCAL T_ACI_RETURN cmhSIM_Write_or_Read_RecordEF ( T_ACI_CMD_SRC srcId, T_ACI_AT_CMD cmd, USHORT datafield, UBYTE record, UBYTE datalen, UBYTE * exchData, void (*rplyCB)(SHORT), T_SIM_ACTP accType, BOOL v_path_info, T_path_info *path_info_ptr); /* +-------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : CMH_SIM | | ROUTINE : cmhSIM_FillInPIN | +-------------------------------------------------------------------+ PURPOSE : fill in the PIN into the PIN field of size length and stuff unused chars with 0xFF. */ GLOBAL void cmhSIM_FillInPIN ( CHAR * PINStr, CHAR * PINFld, UBYTE len ) { UBYTE idx; strncpy( PINFld, PINStr, len ); for( idx = strlen( PINStr ); idx < len; idx++ ) { PINFld[idx] = NOT_PRESENT_CHAR; } } /* +-------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : CMH_SIM | | ROUTINE : cmhSIM_GetHomePLMN | +-------------------------------------------------------------------+ PURPOSE : Extract home PLMN out of the IMSI. */ GLOBAL void cmhSIM_GetHomePLMN ( SHORT * mccBuf, SHORT * mncBuf ) { UBYTE digit; /* holds 4bit digit */ UBYTE i; /* holds counter */ if( simShrdPrm.imsi.c_field EQ 0 ) { /* * No SIM present */ *mccBuf = *mncBuf = -1; } else { /* * SIM present */ *mccBuf = *mncBuf = 0; /* Convert MCC and MNC. */ for (i = 0; i < SIZE_MCC + SIZE_MNC; i++) { digit = (i & 1) ? (simShrdPrm.imsi.field[(i + 1)/2] & 0x0f) : (simShrdPrm.imsi.field[(i + 1)/2] & 0xf0) >> 4; if (i < SIZE_MCC) *mccBuf = (*mccBuf << 4) | digit; else *mncBuf = (*mncBuf << 4) | digit; } /* The only 3 digit mnc codes that are valid are the values between 310 and 316 */ if ((*mccBuf >= 0x310) AND (*mccBuf <= 0x316) OR simShrdPrm.mnc_len EQ 3) { /* used in the US - mcc = 0x310 */ } /* Set the third digit of the MNC to 'F' if the SIM indicates a 2-digit MNC country */ else /* if (simShrdPrm.mnc_len EQ 2) */ { /* The MS digit of the mnc is not valid, so replace the LSB it with 0xF. */ *mncBuf |= 0x00F; } } } /* +-------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | ROUTINE : cmhSIM_plmn_equal_sim | +-------------------------------------------------------------------+ PURPOSE : Return TRUE if the PLMN received equals the PLMN stored on the SIM. This is not exactly the algorithm as shown for HPLMN matching as shown in 03.22 Normative Annex A, this version here is more universal. */ GLOBAL BOOL cmhSIM_plmn_equal_sim (SHORT bcch_mcc, SHORT bcch_mnc, SHORT sim_mcc, SHORT sim_mnc) { /*TRACE_FUNCTION ("cmhSIM_plmn_equal_sim()");*/ /* Check MCC */ if (sim_mcc NEQ bcch_mcc) return FALSE; /* Check first 2 MNC digits */ if ((sim_mnc & 0xff0) NEQ (bcch_mnc & 0xff0)) return FALSE; /* Check for full match */ if ((sim_mnc & 0xf) EQ (bcch_mnc & 0xf)) return TRUE; /* The 3rd digit of the MNC differs */ if ((bcch_mcc >= 0x310) AND (bcch_mcc <= 0x316) OR simShrdPrm.mnc_len EQ 3) { /* * The MCC is in the range 310..316, this means North America. * The zero suffix rule applies. */ return ((((sim_mnc & 0xf) EQ 0xf) AND ((bcch_mnc & 0xf) EQ 0x0)) OR (((sim_mnc & 0xf) EQ 0x0) AND ((bcch_mnc & 0xf) EQ 0xf))); } return ((bcch_mnc & 0xf) EQ 0xf); } /* +-------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : CMH_MM | | ROUTINE : cmhSIM_plmn_is_hplmn | +-------------------------------------------------------------------+ PURPOSE : Return TRUE if the PLMN received is the HPLMN, otherwise return FALSE. */ GLOBAL BOOL cmhSIM_plmn_is_hplmn (SHORT bcch_mcc, SHORT bcch_mnc) { SHORT sim_mcc; /* Holds the MCC of the HPLMN from the SIM */ SHORT sim_mnc; /* Holds the MNC of the HPLMN from the SIM */ TRACE_FUNCTION ("cmhSIM_plmn_is_hplmn()"); if(!cmhMM_GetActingHPLMN(&sim_mcc, &sim_mnc))/*Enhancement Acting HPLMN*/ { /* Extract the HPLMN identification out of the IMSI digits. */ cmhSIM_GetHomePLMN (&sim_mcc, &sim_mnc); } return cmhSIM_plmn_equal_sim (bcch_mcc, bcch_mnc, sim_mcc, sim_mnc); } /* +-------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : CMH_SIM | | ROUTINE : cmhSIM_GetCmeFromSim | +-------------------------------------------------------------------+ PURPOSE : Mapping of SIM error code to ACI error code. */ GLOBAL T_ACI_CME_ERR cmhSIM_GetCmeFromSim ( USHORT errCode ) { switch ( errCode ) { case SIM_NO_ERROR: return CME_ERR_NotPresent; case SIM_CAUSE_PIN1_EXPECT: return CME_ERR_SimPinReq; case SIM_CAUSE_PIN2_EXPECT: return CME_ERR_SimPin2Req; case SIM_CAUSE_PUK1_EXPECT: return CME_ERR_WrongPasswd; case SIM_CAUSE_PIN1_BLOCKED: return CME_ERR_SimPukReq; case SIM_CAUSE_PUK2_EXPECT: return CME_ERR_WrongPasswd; case SIM_CAUSE_PIN2_BLOCKED: return CME_ERR_SimPuk2Req; case SIM_CAUSE_PUK1_BLOCKED: case SIM_CAUSE_PUK2_BLOCKED: return CME_ERR_SimWrong; case SIM_CAUSE_NO_SELECT: case SIM_CAUSE_UNKN_FILE_ID: return CME_ERR_NotFound; case SIM_CAUSE_EF_INVALID: return CME_ERR_OpNotSupp; case SIM_CAUSE_ADDR_WRONG: return CME_ERR_InvIdx; case SIM_CAUSE_CMD_INCONSIST: case SIM_CAUSE_MAX_INCREASE: case SIM_CAUSE_CHV_NOTSET: case SIM_CAUSE_CHV_VALIDATED: return CME_ERR_OpNotAllow; case SIM_CAUSE_ACCESS_PROHIBIT: return CME_ERR_WrongPasswd; case SIM_CAUSE_CARD_REMOVED: case SIM_CAUSE_DRV_NOCARD: return CME_ERR_SimNotIns; case SIM_CAUSE_CLA_WRONG: case SIM_CAUSE_INS_WRONG: case SIM_CAUSE_P1P2_WRONG: case SIM_CAUSE_P3_WRONG: case SIM_CAUSE_PARAM_WRONG: return CME_ERR_PhoneFail; case SIM_CAUSE_SAT_BUSY: return CME_ERR_SimBusy; case SIM_CAUSE_DNL_ERROR: return CME_ERR_Unknown; case SIM_CAUSE_DRV_TEMPFAIL: return CME_ERR_SimFail; default: if (GET_CAUSE_DEFBY(errCode) EQ DEFBY_CONDAT AND GET_CAUSE_ORIGSIDE(errCode) EQ ORIGSIDE_MS) { return CME_ERR_Unknown; } return CME_ERR_Unknown; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_getUserRate | +--------------------------------------------------------------------+ PURPOSE : */ GLOBAL T_ACI_BS_SPEED cmhSIM_GetUserRate ( UBYTE userRate ) { switch( userRate ) { case ( MNCC_UR_0_3_KBIT ): return BS_SPEED_300_V110; case ( MNCC_UR_1_2_KBIT ): return BS_SPEED_1200_V110; case ( MNCC_UR_2_4_KBIT ): return BS_SPEED_2400_V110; case ( MNCC_UR_4_8_KBIT ): return BS_SPEED_4800_V110; case ( MNCC_UR_9_6_KBIT ): return BS_SPEED_9600_V110; case ( MNCC_UR_1_2_KBIT_V23 ): return BS_SPEED_1200_75_V23; case ( MNCC_UR_12_0_KBIT_TRANS ): default: return BS_SPEED_NotPresent; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_getSrvFromSync | +--------------------------------------------------------------------+ PURPOSE : */ GLOBAL T_ACI_CNUM_SERV cmhSIM_GetSrvFromSync ( UBYTE sync ) { switch( sync ) { case ( M_CC_ASYNCHRONOUS ): return CNUM_SERV_Asynch; case ( M_CC_SYNCHRONOUS ): return CNUM_SERV_Synch; default: return CNUM_SERV_NotPresent; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_getSrvFromItc | +--------------------------------------------------------------------+ PURPOSE : */ GLOBAL T_ACI_CNUM_SERV cmhSIM_GetSrvFromItc ( UBYTE itc ) { switch( itc ) { case ( M_CC_ITC_SPEECH ): return CNUM_SERV_Voice; case ( M_CC_ITC_FAX_GROUP_3 ): return CNUM_SERV_Fax; default: return CNUM_SERV_NotPresent; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_getUserRate | +--------------------------------------------------------------------+ PURPOSE : */ GLOBAL T_ACI_CNUM_ITC cmhSIM_GetItc ( UBYTE itc ) { switch( itc ) { case ( M_CC_ITC_DIGITAL_UNRESTRICTED ): return CNUM_ITC_Udi; case ( M_CC_ITC_AUDIO ): return CNUM_ITC_3_1_kHz; default: return CNUM_ITC_NotPresent; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_getMncMccFrmPLMNsel | +--------------------------------------------------------------------+ PURPOSE : get MNC and MCC out of EF PLMNsel entry */ GLOBAL void cmhSIM_getMncMccFrmPLMNsel(const UBYTE *ntry, SHORT *mcc, SHORT *mnc ) { if (memcmp (ntry, PLMNselEmpty, sizeof(PLMNselEmpty)) EQ 0) { *mcc = *mnc = -1; } else { *mcc = ( ntry[0] & 0x0f) << 8; *mcc |= ((ntry[0] >> 4) & 0x0f) << 4; *mcc |= ( ntry[1] & 0x0f); *mnc = ( ntry[2] & 0x0f) << 8; *mnc |= ((ntry[2] >> 4) & 0x0f) << 4; *mnc |= ((ntry[1] >> 4) & 0x0f); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_GetCodedPLMN | +--------------------------------------------------------------------+ PURPOSE : Code MNC and MCC according a EF PLMNsel entry */ GLOBAL BOOL cmhSIM_GetCodedPLMN( const CHAR *oper, T_ACI_CPOL_FRMT format, UBYTE *sim_plmn ) { T_OPER_ENTRY operDesc; /* operator description */ BOOL found; /* get MNC and MCC */ switch( format ) { case( CPOL_FRMT_Long ): found = cmhMM_FindName( &operDesc, oper, CPOL_FRMT_Long ); break; case( CPOL_FRMT_Short ): found = cmhMM_FindName( &operDesc, oper, CPOL_FRMT_Short ); break; case( CPOL_FRMT_Numeric ): found = cmhMM_FindNumeric( &operDesc, oper ); break; default: return( FALSE ); } if( !found ) return( FALSE ); /* code MCC and MNC */ sim_plmn[0] = (operDesc.mcc & 0xf00) >> 8; sim_plmn[0] |= (operDesc.mcc & 0x0f0) ; sim_plmn[1] = (operDesc.mcc & 0x00f) ; sim_plmn[1] |= (operDesc.mnc & 0x00f) << 4; sim_plmn[2] = (operDesc.mnc & 0xf00) >> 8; sim_plmn[2] |= (operDesc.mnc & 0x0f0) ; return( TRUE ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_FillPlmnSelList | +--------------------------------------------------------------------+ PURPOSE : Fills in the CPOL list out of EF PLMNsel and returns the last written index. */ GLOBAL SHORT cmhSIM_FillPlmnSelList ( UBYTE index, T_ACI_CPOL_FRMT frmt, T_ACI_CPOL_OPDESC* operLst, UBYTE length, UBYTE* pData ) { UBYTE idx; /* holds list index */ SHORT off; /* holds PLMNsel offset */ SHORT lastIdx; /* holds last index written to list */ SHORT mcc; /* holds mcc value */ SHORT mnc; /* holds mnc value */ T_OPER_ENTRY OpDsc; /* operator description */ /* *----------------------------------------------------------------- * calculate PLMNsel offset *----------------------------------------------------------------- */ off = (index-1) * ACI_LEN_PLMN_SEL_NTRY; /* *----------------------------------------------------------------- * fill the preferred operator list *----------------------------------------------------------------- */ idx = 0; lastIdx = ACI_NumParmNotPresent; do { /* get mnc and mcc out of PLMNsel field */ cmhSIM_getMncMccFrmPLMNsel( (pData+off), &mcc, & mnc ); /* end of PLMNsel field */ if( off >= length ) { operLst[idx].index = ACI_NumParmNotPresent; operLst[idx].format = CPOL_FRMT_NotPresent; operLst[idx].oper[0] = 0x0; break; } /* valid entry */ if( !(mcc < 0 AND mnc < 0) ) { operLst[idx].index = index; operLst[idx].format = frmt; cmhMM_FindPLMN( &OpDsc, mcc, mnc, NOT_PRESENT_16BIT, FALSE); switch( frmt ) { case( CPOL_FRMT_Long ): if (OpDsc.pnn EQ Read_EONS) { if (OpDsc.long_len) { switch (OpDsc.long_ext_dcs>>4 & 0x07) { case 0x00: utl_cvtPnn7To8((UBYTE *)OpDsc.longName, OpDsc.long_len, OpDsc.long_ext_dcs, (UBYTE *)operLst[idx].oper); break; case 0x01: TRACE_ERROR ("ERROR: Unhandled UCS2"); break; default: TRACE_ERROR ("ERROR: Unknown DCS"); break; } } else { operLst[idx].oper[0] = '\0'; } } else { /* MAX_LONG_OPER_LEN <= MAX_ALPHA_OPER_LEN, no length check needed */ strcpy( operLst[idx].oper, OpDsc.longName ); } break; case( CPOL_FRMT_Short ): if (OpDsc.pnn EQ Read_EONS) { if (OpDsc.shrt_len) { switch (OpDsc.shrt_ext_dcs>>4 & 0x07) { case 0x00: utl_cvtPnn7To8((UBYTE *)OpDsc.shrtName, OpDsc.shrt_len, OpDsc.shrt_ext_dcs, (UBYTE *)operLst[idx].oper); break; case 0x01: TRACE_ERROR ("ERROR: Unhandled UCS2"); break; default: TRACE_ERROR ("ERROR: Unknown DCS"); break; } } else { operLst[idx].oper[0] = '\0'; } } else { /* MAX_SHRT_OPER_LEN <= MAX_ALPHA_OPER_LEN, no length check needed */ strcpy( operLst[idx].oper, OpDsc.shrtName ); } break; case( CPOL_FRMT_Numeric ): /* Implements Measure#32: Row 1037 & 1036 */ cmhMM_mcc_mnc_print(&(operLst[idx].oper[0]), mcc, mnc); break; } idx++; lastIdx = index; } off += ACI_LEN_PLMN_SEL_NTRY; index++; } while( idx < MAX_OPER ); return( lastIdx ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_UsdPlmnSelNtry | +--------------------------------------------------------------------+ PURPOSE : Counts the used entries of the preferred PLMN list and returns the number of used entries. */ GLOBAL SHORT cmhSIM_UsdPlmnSelNtry ( UBYTE length, UBYTE* pData ) { UBYTE idx; /* holds list index */ SHORT off; /* holds PLMNsel offset */ UBYTE maxNtry; /* holds the maximum number of entries */ SHORT used; /* holds number of used entries */ SHORT mcc; /* holds mcc value */ SHORT mnc; /* holds mnc value */ /* *----------------------------------------------------------------- * count the used entries *----------------------------------------------------------------- */ maxNtry = length / ACI_LEN_PLMN_SEL_NTRY; for( idx = 0, used = 0, off = 0; idx < maxNtry; idx++, off += ACI_LEN_PLMN_SEL_NTRY ) { /* get mnc and mcc out of PLMNsel field */ cmhSIM_getMncMccFrmPLMNsel( (pData+off), &mcc, & mnc ); /* valid entry */ if( !(mcc < 0 AND mnc < 0) ) { used++; } } return( used ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_CmpctPlmnSel | +--------------------------------------------------------------------+ PURPOSE : Shoves entries of preferred PLMN list to remove empty entries of the list. */ GLOBAL void cmhSIM_CmpctPlmnSel ( UBYTE length, UBYTE* pData ) { UBYTE maxNtry; /* holds the maximum number of entries */ UBYTE lstIdx; /* holds list index */ UBYTE* dstNtry; /* points to destination entry index */ /* *----------------------------------------------------------------- * compact the list *----------------------------------------------------------------- */ lstIdx = 0; dstNtry = pData; maxNtry = length / ACI_LEN_PLMN_SEL_NTRY; while( lstIdx < maxNtry ) { if(memcmp( pData, PLMNselEmpty, sizeof(PLMNselEmpty))) { if( pData NEQ dstNtry ) { memcpy( dstNtry, pData, ACI_LEN_PLMN_SEL_NTRY ); memcpy( pData, PLMNselEmpty, ACI_LEN_PLMN_SEL_NTRY); } dstNtry += ACI_LEN_PLMN_SEL_NTRY; } lstIdx++; pData += ACI_LEN_PLMN_SEL_NTRY; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMS | | STATE : code ROUTINE : cmhSIM_UpdPlmnSel | +--------------------------------------------------------------------+ PURPOSE : This function updates the indexed EF PLMN SEL entry and writes the field to the SIM. */ GLOBAL T_ACI_RETURN cmhSIM_UpdPlmnSel ( T_ACI_CMD_SRC srcId, SHORT index, UBYTE *plmn, T_ACI_CPOL_MOD mode ) { SHORT off; /* holds EF offset */ SHORT cpyOff; /* holds offset for copy operation */ UBYTE maxIdx; /* holds maximum number of index */ TRACE_FUNCTION ("cmhSIM_UpdPlmnSel()"); /* *----------------------------------------------------------------- * update EF PLMNsel RAM copy *----------------------------------------------------------------- */ maxIdx = CPOLSimEfDataLen / ACI_LEN_PLMN_SEL_NTRY; off = (index-1) * ACI_LEN_PLMN_SEL_NTRY; if( mode EQ CPOL_MOD_Insert AND index < maxIdx ) { cmhSIM_CmpctPlmnSel ( CPOLSimEfDataLen, CPOLSimEfData ); cpyOff = (maxIdx-1) * ACI_LEN_PLMN_SEL_NTRY; cpyOff -= ACI_LEN_PLMN_SEL_NTRY; /* need not copy since last index will fall out of list! */ while( cpyOff >= off AND cpyOff >= 0 ) { memcpy( CPOLSimEfData+cpyOff+ACI_LEN_PLMN_SEL_NTRY, CPOLSimEfData+cpyOff, ACI_LEN_PLMN_SEL_NTRY ); cpyOff -= ACI_LEN_PLMN_SEL_NTRY; } } memcpy( CPOLSimEfData+off, plmn, ACI_LEN_PLMN_SEL_NTRY ); /* Implements Measure 150 and 159 */ return ( cmhSIM_Req_or_Write_PlmnSel( srcId, ACT_WR_DAT ) ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMS | | STATE : code ROUTINE : cmhSIM_FndEmptyPlmnSel | +--------------------------------------------------------------------+ PURPOSE : This function searches for an empty entry in EF PLMN SEL, fills it and writes the field to the SIM. */ GLOBAL T_ACI_RETURN cmhSIM_FndEmptyPlmnSel ( T_ACI_CMD_SRC srcId, UBYTE *plmn ) { UBYTE maxNtry; /* holds maximum number of entries */ SHORT off; /* holds EF offset */ TRACE_FUNCTION ("cmhSIM_FndEmptyPlmnSel()"); /* *----------------------------------------------------------------- * search for an empty entry, and update *----------------------------------------------------------------- */ maxNtry = CPOLSimEfDataLen / ACI_LEN_PLMN_SEL_NTRY; for( off = 0; maxNtry > 0; off += ACI_LEN_PLMN_SEL_NTRY, maxNtry-- ) { if( !memcmp( CPOLSimEfData+off, PLMNselEmpty, ACI_LEN_PLMN_SEL_NTRY )) { memcpy( CPOLSimEfData+off, plmn, ACI_LEN_PLMN_SEL_NTRY ); /* Implements Measure 150 and 159 */ return ( cmhSIM_Req_or_Write_PlmnSel( srcId, ACT_WR_DAT ) ); } } ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_MemFull ); return( AT_FAIL ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMS | | STATE : code ROUTINE : cmhSIM_DelPlmnSel | +--------------------------------------------------------------------+ PURPOSE : This function updates the indexed EF PLMN SEL entry and writes the field to the SIM. */ GLOBAL T_ACI_RETURN cmhSIM_DelPlmnSel ( T_ACI_CMD_SRC srcId, SHORT index, T_ACI_CPOL_MOD mode ) { SHORT off; /* holds EF offset */ TRACE_FUNCTION ("cmhSIM_DelPlmnSel()"); /* *----------------------------------------------------------------- * delete entry in EF PLMNsel RAM copy *----------------------------------------------------------------- */ off = (index-1) * ACI_LEN_PLMN_SEL_NTRY; memcpy( CPOLSimEfData+off, PLMNselEmpty, ACI_LEN_PLMN_SEL_NTRY ); if( mode EQ CPOL_MOD_CompactList ) cmhSIM_CmpctPlmnSel ( CPOLSimEfDataLen, CPOLSimEfData ); /* Implements Measure 150 and 159 */ return ( cmhSIM_Req_or_Write_PlmnSel( srcId, ACT_WR_DAT ) ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMS | | STATE : code ROUTINE : cmhSIM_ChgPlmnSel | +--------------------------------------------------------------------+ PURPOSE : This function exchanges the indexed EF PLMN SEL entries and writes the field to the SIM. */ GLOBAL T_ACI_RETURN cmhSIM_ChgPlmnSel ( T_ACI_CMD_SRC srcId, SHORT index, SHORT index2 ) { SHORT off1, off2; /* holds EF offset */ UBYTE plmn1[ACI_LEN_PLMN_SEL_NTRY]; /* buffers PLMN 1 */ UBYTE plmn2[ACI_LEN_PLMN_SEL_NTRY]; /* buffers PLMN 2 */ TRACE_FUNCTION ("cmhSIM_ChgPlmnSel()"); /* *----------------------------------------------------------------- * change entries in EF PLMNsel RAM copy *----------------------------------------------------------------- */ off1 = (index-1) * ACI_LEN_PLMN_SEL_NTRY; off2 = (index2-1) * ACI_LEN_PLMN_SEL_NTRY; memcpy( plmn1, CPOLSimEfData+off1, ACI_LEN_PLMN_SEL_NTRY ); memcpy( plmn2, CPOLSimEfData+off2, ACI_LEN_PLMN_SEL_NTRY ); memcpy( CPOLSimEfData+off1, plmn2, ACI_LEN_PLMN_SEL_NTRY ); memcpy( CPOLSimEfData+off2, plmn1, ACI_LEN_PLMN_SEL_NTRY ); /* Implements Measure 150 and 159 */ return ( cmhSIM_Req_or_Write_PlmnSel( srcId, ACT_WR_DAT ) ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_WriteTranspEF | +--------------------------------------------------------------------+ PURPOSE : This function starts writing of a transparent EF to SIM. (SIM only busy with valid 'srcId') */ GLOBAL T_ACI_RETURN cmhSIM_WriteTranspEF (T_ACI_CMD_SRC srcId, T_ACI_AT_CMD cmd, BOOL v_path_info, T_path_info *path_info_ptr, USHORT datafield, USHORT offset, UBYTE datalen, UBYTE * exchData, void (*rplyCB)(SHORT)) { /* Implements Measure 158 */ return ( cmhSIM_Write_or_Read_TranspEF( srcId, cmd, datafield, offset, datalen,exchData, rplyCB, ACT_WR_DAT ,v_path_info,path_info_ptr) ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_ReadTranspEF | +--------------------------------------------------------------------+ PURPOSE : This function starts reading of EF PLMN SEL from SIM. (SIM only busy with valid 'srcId') */ GLOBAL T_ACI_RETURN cmhSIM_ReadTranspEF ( T_ACI_CMD_SRC srcId, T_ACI_AT_CMD cmd, BOOL v_path_info, T_path_info *path_info_ptr, USHORT datafield, USHORT offset, UBYTE explen, UBYTE * exchData, void (*rplyCB)(SHORT)) { /* Implements Measure 158 */ return ( cmhSIM_Write_or_Read_TranspEF( srcId, cmd, datafield, offset, explen, exchData, rplyCB, ACT_RD_DAT,v_path_info,path_info_ptr ) ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_WriteRecordEF | +--------------------------------------------------------------------+ PURPOSE : This function starts writing of a transparent EF to SIM. (SIM only busy with valid 'srcId') */ GLOBAL T_ACI_RETURN cmhSIM_WriteRecordEF (T_ACI_CMD_SRC srcId, T_ACI_AT_CMD cmd, BOOL v_path_info, T_path_info *path_info_ptr, USHORT datafield, UBYTE record, UBYTE datalen, UBYTE * exchData, void (*rplyCB)(SHORT)) { /* Implements Measure 168 */ return ( cmhSIM_Write_or_Read_RecordEF ( srcId, cmd, datafield, record, datalen, exchData, rplyCB, ACT_WR_REC ,v_path_info,path_info_ptr) ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_ReadRecordEF | +--------------------------------------------------------------------+ PURPOSE : This function starts reading of EF PLMN SEL from SIM. (SIM only busy with valid 'srcId') */ GLOBAL T_ACI_RETURN cmhSIM_ReadRecordEF ( T_ACI_CMD_SRC srcId, T_ACI_AT_CMD cmd, BOOL v_path_info, T_path_info *path_info_ptr, USHORT datafield, UBYTE record, UBYTE explen, UBYTE * exchData, void (*rplyCB)(SHORT)) { /* Implements Measure 168 */ return ( cmhSIM_Write_or_Read_RecordEF ( srcId, cmd, datafield, record, explen, exchData, rplyCB, ACT_RD_REC ,v_path_info,path_info_ptr) ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : SimStatusError | +--------------------------------------------------------------------+ PURPOSE : sync_notification: TRUE if notification through asynchrone callback FALSE if notif. whithin synchrone context. */ #define GetSIMError (1) #define CheckSimStatus (0) LOCAL T_ACI_RETURN SimStatusError ( T_ACI_CMD_SRC srcBuf, T_ACI_AT_CMD cmdBuf, UBYTE sync_notification) { T_ACI_CPIN_RSLT code = CPIN_RSLT_NotPresent; T_ACI_CME_ERR err = CME_ERR_NotPresent; /* trace if needed... TRACE_EVENT_P1("simShrdPrm.SIMStat: %d", simShrdPrm.SIMStat); */ switch( simShrdPrm.SIMStat ) { case( SS_OK ): if ( qAT_PlusCPIN(CMD_SRC_LCL, &code) EQ AT_CMPL ) { switch ( code ) { case CPIN_RSLT_PhSimPinReq: err = CME_ERR_PhSimPinReq; break; case CPIN_RSLT_SimPinReq: err = CME_ERR_SimPinReq; break; case CPIN_RSLT_SimPin2Req: err = CME_ERR_SimPin2Req; break; case(CPIN_RSLT_PhFSimPinReq): err = CME_ERR_PhFSimPinReq; break; case(CPIN_RSLT_PhFSimPukReq): err = CME_ERR_PhFSimPukReq; break; case(CPIN_RSLT_PhNetPinReq): err = CME_ERR_NetworkPersPinReq; break; case(CPIN_RSLT_PhNetPukReq): err = CME_ERR_NetworkPersPukReq; break; case(CPIN_RSLT_PhNetSubPinReq): err = CME_ERR_NetworkSubsetPersPinReq; break; case(CPIN_RSLT_PhNetSubPukReq): err = CME_ERR_NetworkSubsetPersPukReq; break; case(CPIN_RSLT_PhSPPinReq): err = CME_ERR_ProviderPersPinReq; break; case(CPIN_RSLT_PhSPPukReq): err = CME_ERR_ProviderPersPukReq; break; case(CPIN_RSLT_PhCorpPinReq): err = CME_ERR_CorporatePersPinReq; break; case(CPIN_RSLT_PhCorpPukReq): err = CME_ERR_CorporatePersPukReq; break; } } break; case( SS_BLKD ): if ( qAT_PlusCPIN(CMD_SRC_LCL, &code) EQ AT_CMPL ) { switch ( code ) { case CPIN_RSLT_SimPukReq: err = CME_ERR_SimPukReq; break; case CPIN_RSLT_SimPuk2Req: err = CME_ERR_SimPuk2Req; break; } } break; case( SS_INV ): err = CME_ERR_SimWrong; break; case( SS_URCHB ): err = CME_ERR_SimFail; break; default: /* unexpected result */ break; } if( err EQ CME_ERR_NotPresent ) { return ( AT_FAIL ); } else { TRACE_EVENT_P1("err: %d", err); } switch( sync_notification ) { case( GetSIMError ): R_AT( RAT_CME, srcBuf ) ( cmdBuf, err ); break; case( CheckSimStatus ): ACI_ERR_DESC( ACI_ERR_CLASS_Cme, err ); break; } return( AT_CMPL ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_GetSIMError | +--------------------------------------------------------------------+ PURPOSE : This function is used to request the SIM error status. */ GLOBAL T_ACI_RETURN cmhSIM_GetSIMError ( T_ACI_CMD_SRC srcBuf, T_ACI_AT_CMD cmdBuf ) { TRACE_FUNCTION("cmhSIM_GetSIMError"); return(SimStatusError( srcBuf, cmdBuf, GetSIMError )); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_GetSIMError | +--------------------------------------------------------------------+ PURPOSE : This function is used to check the SIM pin status. */ GLOBAL T_ACI_RETURN cmhSIM_CheckSimPinStatus ( T_ACI_CMD_SRC srcBuf, T_ACI_AT_CMD cmdBuf ) { TRACE_FUNCTION("cmhSIM_CheckSimPinStatus"); return(SimStatusError( srcBuf, cmdBuf, CheckSimStatus )); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_CheckSimStatus| +--------------------------------------------------------------------+ PURPOSE : This function is used to check the SIM pin status using global parameters. */ GLOBAL BOOL cmhSIM_CheckSimStatus ( ) { TRACE_FUNCTION("cmhSIM_CheckSimStatus()"); /* *----------------------------------------------------------------- * check SIM status *----------------------------------------------------------------- */ switch (simShrdPrm.SIMStat) { case NO_VLD_SS: ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimFail ); break; case SS_INV: ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimWrong ); break; case SS_URCHB: ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimNotIns ); break; case SS_BLKD: switch (simShrdPrm.PINStat) { case PS_PUK1: ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimPukReq); break; case PS_PUK2: ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimPuk2Req); break; } break; case SS_OK: switch (simShrdPrm.PINStat) { case PS_RDY: return (TRUE); case PS_PIN1: ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimPinReq); break; case PS_PIN2: ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimPin2Req ); break; case PS_PUK1: ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimPukReq); break; case PS_PUK2: ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimPuk2Req); break; default: ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimFail ); break; } break; } return FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : getSupLangFromPCM | +--------------------------------------------------------------------+ PURPOSE : get Supported Language from PCM and compare it with Language table. */ GLOBAL T_ACI_RETURN getSupLangFromPCM ( T_ACI_LAN_SUP *lanlst, SHORT *lastIdx) { pcm_FileInfo_Type fileInfo; EF_MSSUP mssup; LONG value; SHORT i, idx=0; LONG bitmask = 0x01; TRACE_FUNCTION ("getSupLangFromPCM()"); /* *------------------------------------------------------------------- * read supported language from ME *------------------------------------------------------------------- */ /* Implements Measure#32: Row 60 & 1039 */ if (pcm_GetFileInfo ( (UBYTE*)ef_mssup_id, &fileInfo) NEQ PCM_OK) { TRACE_EVENT("Error getting datas from PCM"); ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_MemFail ); return( AT_FAIL ); } else { /* Implements Measure#32: Row 60 & 1039 */ if ( pcm_ReadFile ( ( UBYTE* )ef_mssup_id,fileInfo.FileSize, ( UBYTE*) &mssup, &fileInfo.Version) EQ PCM_OK ) { value =mssup.lng1; value |=mssup.lng2 <<8; value |=mssup.lng3 <<16; for(i=0;i<MAX_LAN;i++) { if (bitmask & value) { lanlst[idx].lng =(T_ACI_CLAN_LNG)i; idx++; } bitmask= bitmask<< 1; } } else { ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_MemFail ); return( AT_FAIL ); } } /* *------------------------------------------------------------------- * terminate list and set last index *------------------------------------------------------------------- */ if( idx < MAX_LAN ) { lanlst[idx].str = 0x0; lanlst[idx].lng = CLAN_LNG_ENG; } *lastIdx = idx; /* *------------------------------------------------------------------- * compare the code of supported language in PCM with * Language table to get the char code *------------------------------------------------------------------- */ for(i=0;i < *lastIdx;i++) { idx=0; while (lngs[idx].str NEQ NULL AND lngs[idx].lng NEQ lanlst[i].lng) idx++; if (lngs[idx].lng EQ lanlst[i].lng) lanlst[i].str=lngs[idx].str; } return( AT_CMPL ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : checkSuppLangInELP | +--------------------------------------------------------------------+ PURPOSE : check if the language to be read from the EF ELP is supported in PCM SupLng: is true if the language is supprted else False */ GLOBAL BOOL checkSuppLang (T_ACI_LAN_SUP *lanlst, SHORT lastIdx, T_ACI_LAN_SUP *clng) { USHORT i; BOOL SupLng=FALSE; /* *----------------------------------------------------------------- * check if the Language from EF ELP is supported in PCM *----------------------------------------------------------------- */ for(i=0;i < lastIdx;i++) { if (!strcmp(lanlst[i].str,clng->str) ) { clng->lng=lanlst[i].lng; SupLng= TRUE; break; } } return( SupLng ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : checkSuppLangInLP | +--------------------------------------------------------------------+ PURPOSE : check if the language to be read from the EF LP is supported in PCM SupLng: is true if the language is supprted else False */ GLOBAL BOOL checkSuppLangInLP(T_ACI_LAN_SUP *lanlst,SHORT lastIdx, T_ACI_LAN_SUP *clng) { USHORT i; BOOL SupLng=FALSE; /* *----------------------------------------------------------------- * check if the Language from EF LP is supported in PCM *----------------------------------------------------------------- */ for(i=0;i < lastIdx;i++) { if (lanlst[i].lng EQ clng->lng ) { clng->str=lanlst[i].str; SupLng= TRUE; break; } } return( SupLng ); } #if 0 /* +------------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMS | | STATE : code ROUTINE : cmhSIM_LanguageLP_Update| +------------------------------------------------------------------------+ PURPOSE : */ GLOBAL BOOL cmhSIM_LanguageLP_Update ( int ref, T_SIM_FILE_UPDATE_IND *fu) { T_ACI_CMD_SRC ownBuf; /* buffers current owner */ UBYTE i; BOOL found = FALSE; char *auptr="au"; CHAR *ef = EF_CLNG_ID; pcm_FileInfo_Type fileInfo; EF_CLNG lng; TRACE_FUNCTION ("cmhSIM_LanguageLP_Update()"); ownBuf = simEntStat.entOwn; for (i = 0; i < (int)fu->val_nr; i++) { if (!found AND (fu->file_info[i].datafiled EQ SIM_LP)) { found = TRUE; } } if (found) { /* *------------------------------------------------------------------- * read supported language from ME *------------------------------------------------------------------- */ if (pcm_GetFileInfo ( ( UBYTE* ) ef, &fileInfo) NEQ PCM_OK) { TRACE_EVENT("cmhSIM_LanguageLP_Update: error returned by pcm_GetFileInfo()" ); return TRUE; } else { if ( pcm_ReadFile ( (UBYTE*)ef, fileInfo.FileSize, (UBYTE*) &lng, &fileInfo.Version) EQ PCM_OK ) { } else { TRACE_EVENT("cmhSIM_LanguageLP_Update: error returned by pcm_ReadFile()" ); return TRUE; } } /* *------------------------------------------------------------------- * Read EF LP from the sim if Automatic language is selected *------------------------------------------------------------------- */ if (!strncmp((char*)&lng.data[0], auptr, 2)) { cmhSIM_ReqLanguageLP(ownBuf); /* reading files */ simShrdPrm.fuRef = (UBYTE)ref; return FALSE; } else { return TRUE; } } else { return TRUE; /* nothing to do */ } } #endif /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_AD_Update | +--------------------------------------------------------------------+ PURPOSE : This function is used to request the SIM Administrative Data (EF_AD). */ GLOBAL BOOL cmhSIM_AD_Update (int ref, T_SIM_FILE_UPDATE_IND *fu) { /* Implements Measure 42 */ return ( cmhSIM_AD_CSP_Update( ref, fu, SIM_AD ) ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_Read_AD | +--------------------------------------------------------------------+ PURPOSE : This function is used to request the SIM Administrative Data (EF_AD). */ GLOBAL T_ACI_RETURN cmhSIM_Read_AD() { SHORT table_id; TRACE_FUNCTION ("cmhSIM_Read_AD()"); table_id = psaSIM_atbNewEntry(); if(table_id NEQ NO_ENTRY) { simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; simShrdPrm.atb[table_id].accType = ACT_RD_DAT; simShrdPrm.atb[table_id].v_path_info = FALSE; simShrdPrm.atb[table_id].reqDataFld = SIM_AD; simShrdPrm.atb[table_id].dataOff = 0; simShrdPrm.atb[table_id].dataLen = NOT_PRESENT_8BIT; simShrdPrm.atb[table_id].recMax = 0; simShrdPrm.atb[table_id].exchData = NULL; simShrdPrm.atb[table_id].rplyCB = cmhSIM_Read_AD_cb; simShrdPrm.aId = table_id; if(psaSIM_AccessSIMData() < 0) { TRACE_EVENT("FATAL ERROR"); return ( AT_FAIL ); } return ( AT_CMPL ); } return ( AT_FAIL ); } /* +-------------------------------------------------------------------+ | PROJECT : MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_EvalMNCLength | +-------------------------------------------------------------------+ PURPOSE : This function evaluates the MNC length by extracting MNC from IMSI and comparing it with the MNC in operListFixed. */ #ifdef TI_PS_OP_OPN_TAB_ROMBASED GLOBAL UBYTE cmhSIM_EvalMNCLength(void) { UBYTE digit; /* holds 4bit digit */ USHORT i; /* holds counter */ SHORT sim_mcc; /* holds mcc from operListFixed */ SHORT sim_mnc; /* holds mnc from operListFixed */ SHORT mcc; /* holds mcc extracted from IMSI */ SHORT mnc; /* holds mnc extracted from IMSI */ /* Changes for ROM data */ const UBYTE *plmn_comp_entry; /* get a local pointer holder */ T_OPER_ENTRY oper; mcc = mnc = 0; /* Initialize mcc, mnc */ for (i = 0; i < SIZE_MCC + SIZE_MNC; i++) /* Extract MCC and MNC. */ { digit = (i & 1) ? (simShrdPrm.imsi.field[(i + 1)/2] & 0x0f) : (simShrdPrm.imsi.field[(i + 1)/2] & 0xf0) >> 4; if (i < SIZE_MCC) { mcc = (mcc << 4) | digit; } else { mnc = (mnc << 4) | digit; } } /* Changes for ROM data */ plmn_comp_entry = ptr_plmn_compressed; /* Get first compressed PLMN entry */ while (cmhMM_decodePlmn (&oper, plmn_comp_entry) EQ 0) { sim_mcc = oper.mcc; sim_mnc = oper.mnc; if ( sim_mcc EQ mcc ) { if ( (sim_mnc & 0xff0) EQ (mnc & 0xff0) ) { if ( (sim_mnc & 0x0f) EQ 0x0f ) { return 2; } else { return 3; } } } /* Next compressed PLMN entry */ plmn_comp_entry += cmhMM_PlmnEntryLength (plmn_comp_entry); } return NOT_PRESENT_8BIT; } #else GLOBAL UBYTE cmhSIM_EvalMNCLength(void) { UBYTE digit; /* holds 4bit digit */ USHORT i; /* holds counter */ SHORT sim_mcc; /* holds mcc from operListFixed */ SHORT sim_mnc; /* holds mnc from operListFixed */ SHORT mcc; /* holds mcc extracted from IMSI */ SHORT mnc; /* holds mnc extracted from IMSI */ mcc = mnc = 0; /* Initialize mcc, mnc */ for (i = 0; i < SIZE_MCC + SIZE_MNC; i++) /* Extract MCC and MNC. */ { digit = (i & 1) ? (simShrdPrm.imsi.field[(i + 1)/2] & 0x0f) : (simShrdPrm.imsi.field[(i + 1)/2] & 0xf0) >> 4; if (i < SIZE_MCC) mcc = (mcc << 4) | digit; else mnc = (mnc << 4) | digit; } for( i = 0; operListFixed[i].mcc NEQ -1 AND operListFixed[i].mnc NEQ -1; i++ ) /* Evaluate mnc length */ { sim_mcc = operListFixed[i].mcc; sim_mnc = operListFixed[i].mnc; if ( sim_mcc EQ mcc ) { if ( (sim_mnc & 0xff0) EQ (mnc & 0xff0) ) { if ( (sim_mnc & 0x0f) EQ 0x0f ) { return 2; } else { return 3; } } } } return NOT_PRESENT_8BIT; } #endif /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_Read_AD_cb | +--------------------------------------------------------------------+ PURPOSE : Call back for SIM read (EF_AD). */ void cmhSIM_Read_AD_cb(SHORT table_id) { TRACE_FUNCTION ("cmhSIM_Read_AD_cb()"); if ( simShrdPrm.atb[table_id].reqDataFld EQ SIM_AD ) { if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR ) { cmhSIM_AD_Updated(simShrdPrm.atb[table_id].dataLen, simShrdPrm.atb[table_id].exchData); } #ifdef SIM_TOOLKIT if (simShrdPrm.fuRef >= 0) { psaSAT_FUConfirm (simShrdPrm.fuRef, (USHORT)((simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR)? SIM_FU_SUCCESS: SIM_FU_ERROR)); } #endif } simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_Access_AD | +--------------------------------------------------------------------+ PURPOSE : Access the AD data */ GLOBAL void cmhSIM_AD_Updated(UBYTE ad_len, UBYTE* ad_data) { TRACE_FUNCTION("cmhSIM_AD_Updated()"); /* * byte 2 and byte 3 of EF AD have only a meaning * if the bit1 of byte 1 is set */ if (ad_data[0] & 0x01) { if (ad_data[2] & 0x01) { /* ci enabled on SIM */ simShrdPrm.ciSIMEnabled = TRUE; } else { /* ci disabled on SIM, don't show indications */ simShrdPrm.ciSIMEnabled = FALSE; } } /* byte 4 is optional */ if (ad_len >= 4) { switch (ad_data[3] & 0x0F) { case 2: simShrdPrm.mnc_len = 2; break; case 3: simShrdPrm.mnc_len = 3; break; default: simShrdPrm.mnc_len =NOT_PRESENT_8BIT; } } else { simShrdPrm.mnc_len = NOT_PRESENT_8BIT; } if (simShrdPrm.mnc_len NEQ 3) /* Update MNC length */ { simShrdPrm.mnc_len = cmhSIM_EvalMNCLength(); } } /* +--------------------------------------------------------------------+ | PROJECT : EONS MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_OpUpdate | +--------------------------------------------------------------------+ PURPOSE : This function will be used to process the update of EFopl and EFpnn. */ GLOBAL BOOL cmhSIM_OpUpdate (int ref, T_SIM_FILE_UPDATE_IND *fu) { UBYTE i; BOOL ps_is_not_reading_files_1 = FALSE, ps_is_not_reading_files_2 = FALSE; TRACE_FUNCTION ("cmhSIM_OpUpdate()"); for (i = 0; i < (int)fu->val_nr; i++) { if(fu->file_info[i].v_path_info EQ TRUE AND fu->file_info[i].path_info.df_level1 EQ SIM_DF_GSM AND fu->file_info[i].path_info.v_df_level2 EQ FALSE) { switch(fu->file_info[i].datafield) { case SIM_OPL: TRACE_EVENT("EF_OPL has been updated "); ps_is_not_reading_files_1 = cmhSIM_UpdateOperatorName(SIM_OPL); /*lint -fallthrough */ case SIM_PNN: if(fu->file_info[i].datafield NEQ SIM_OPL) { TRACE_EVENT("EF_PNN has been updated "); } ps_is_not_reading_files_2 = !cmhMM_OpUpdateName(); cmhMM_Registered(); simShrdPrm.fuRef = (UBYTE)ref; if(ps_is_not_reading_files_1 OR ps_is_not_reading_files_2) { return(TRUE); } return(FALSE); /* reading files ? */ default: break; } } } return(TRUE); /* nothing to do */ } /* +-------------------------------------------------------------------+ | PROJECT : EONS MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_BuildOPLList | +-------------------------------------------------------------------+ PURPOSE : */ LOCAL void cmhSIM_BuildOPLList(SHORT table_id) { UBYTE *data = simShrdPrm.atb[table_id].exchData; T_opl *opl_entry = &simShrdPrm.opl_list.opl_rcd[simShrdPrm.opl_list.num_rcd]; /* Test if record is valid */ /* opl_entry->plmn.v_plmn = (data[0] EQ 0xFF) ? INVLD_PLMN : VLD_PLMN; */ /* Copy MCC and MNC from SIM data to OPL list */ memcpy (opl_entry->plmn, data, UBYTES_PER_PLMN); /* Extract LAC from SIM data and copy to OPL list*/ opl_entry->lac1 = data[3] << 8 | data[4]; opl_entry->lac2 = data[5] << 8 | data[6]; /* Extract PNN record number from SIM data and copy to OPL list*/ opl_entry->pnn_rec_num = data[7]; } /* +-------------------------------------------------------------------+ | PROJECT : EONS MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_OpReadOplRcdCb | +-------------------------------------------------------------------+ PURPOSE : Call back for SIM retrieval of EF_OPL. */ GLOBAL void cmhSIM_OpReadOplRcdCb(SHORT table_id) { TRACE_FUNCTION("cmhSIM_OpReadOplRcdCb"); /* Implements Measure 120 */ cmhSIM_OpRead_simDataFld_RcdCb( table_id, SIM_OPL ); } /* +-------------------------------------------------------------------+ | PROJECT : EONS MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_BuildPnnList | +-------------------------------------------------------------------+ PURPOSE : decodes EF_PNN record read from SIM */ LOCAL void cmhSIM_BuildPnnList(SHORT table_id) { UBYTE *data = simShrdPrm.atb[table_id].exchData; T_pnn *pnn_entry = &simShrdPrm.pnn_list.pnn_rcd[simShrdPrm.pnn_list.num_rcd]; if (*data++ EQ PNN_LONG_NAME_IEI) { pnn_entry->v_plmn = TRUE; pnn_entry->long_len = (*data++)-1; /* adjust dcs */ pnn_entry->long_ext_dcs = *data++; memcpy(pnn_entry->long_name, data, MINIMUM(pnn_entry->long_len, sizeof(pnn_entry->long_name))); data += pnn_entry->long_len; /*----- IEI PNN short name ------*/ if (*data++ EQ PNN_SHORT_NAME_IEI) { pnn_entry->shrt_len = (*data++)-1; /* adjust dcs */ pnn_entry->shrt_ext_dcs = *data++; memcpy(pnn_entry->shrt_name, data, MINIMUM(pnn_entry->shrt_len, sizeof(pnn_entry->shrt_name))); } else { pnn_entry->shrt_len = 0; } } else { /* marc record as unused */ pnn_entry->v_plmn = FALSE; pnn_entry->long_len = pnn_entry->shrt_len = 0; } simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; } /* +-------------------------------------------------------------------+ | PROJECT : EONS MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_OpReadPnnRcdCb | +-------------------------------------------------------------------+ PURPOSE : Call back for SIM retrieval of EF_PNN. */ GLOBAL void cmhSIM_OpReadPnnRcdCb(SHORT table_id) { TRACE_FUNCTION("cmhSIM_OpReadPnnRcdCb"); /* Implements Measure 120 */ cmhSIM_OpRead_simDataFld_RcdCb( table_id, SIM_PNN ); } /* +-------------------------------------------------------------------+ | PROJECT : EONS MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_StartOperatorName | +-------------------------------------------------------------------+ PURPOSE : Start retireval of EF_OPL from SIM */ GLOBAL BOOL cmhSIM_StartOperatorName() { TRACE_FUNCTION ("cmhSIM_StartOperatorName()"); /* If EF_PNN and/or EF_OPL are allocated then start retrieval of from EF_OPL */ if (simShrdPrm.opl_list.num_rcd EQ 0 AND psaSIM_ChkSIMSrvSup(SRV_PNN) AND psaSIM_ChkSIMSrvSup(SRV_OPL)) { TRACE_EVENT (" start reading SIM_OPL"); /* Implements Measure 135 */ return ( !cmhSIM_OpRead_Opl_or_Pnn_Rcd(1, SIM_OPL, cmhSIM_OpReadOplRcdCb)); } if (simShrdPrm.pnn_list.num_rcd EQ 0 AND psaSIM_ChkSIMSrvSup(SRV_PNN)) { TRACE_EVENT (" start reading SIM_PNN"); /* Implements Measure 135 */ return ( !cmhSIM_OpRead_Opl_or_Pnn_Rcd(1, SIM_PNN, cmhSIM_OpReadPnnRcdCb)); } TRACE_EVENT (" reading finished!"); if(psaSIM_ChkSIMSrvSup(SRV_PNN)) { if (simShrdPrm.pnn_list.pnn_status EQ TRUE) { percentCSTAT_indication(STATE_MSG_EONS, ENTITY_STATUS_Ready); } else if (psaSIM_ChkSIMSrvSup(SRV_OPL) AND simShrdPrm.opl_list.opl_status EQ TRUE) { percentCSTAT_indication(STATE_MSG_EONS, ENTITY_STATUS_Ready); } else { percentCSTAT_indication(STATE_MSG_EONS, ENTITY_STATUS_NotReady); } } else { percentCSTAT_indication(STATE_MSG_EONS, ENTITY_STATUS_NotReady); } if (mmShrdPrm.regStat EQ RS_FULL_SRV) { cmhMM_Registered(); } return(TRUE); } /* +-------------------------------------------------------------------+ | PROJECT : EONS MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_UpdateOperatorName | +-------------------------------------------------------------------+ PURPOSE : Start File Update of EF_OPL from SIM */ GLOBAL BOOL cmhSIM_UpdateOperatorName(USHORT reqDataFld) { int i; TRACE_FUNCTION ("cmhSIM_UpdateOperatorName()"); if (reqDataFld EQ SIM_OPL OR reqDataFld EQ NOT_PRESENT_16BIT) { simShrdPrm.opl_list.num_rcd = 0; for (i=0; i<OPL_MAX_RECORDS; i++) { memcpy (simShrdPrm.opl_list.opl_rcd[i].plmn, PLMNselEmpty, UBYTES_PER_PLMN); } } if (reqDataFld EQ SIM_PNN OR reqDataFld EQ NOT_PRESENT_16BIT) { simShrdPrm.pnn_list.num_rcd = 0; for (i=0; i<PNN_MAX_RECORDS; i++) { simShrdPrm.pnn_list.pnn_rcd[i].v_plmn=FALSE; } } return (!cmhSIM_StartOperatorName()); } GLOBAL T_opl_field* cmhSIM_GetOPL() { return &simShrdPrm.opl_list; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_Read_AD | +--------------------------------------------------------------------+ PURPOSE : This function returns the current PLMN mode bit value */ GLOBAL UBYTE cmhSIM_isplmnmodebit_set() { return simShrdPrm.PLMN_Mode_Bit; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_ONS_Update | +--------------------------------------------------------------------+ PURPOSE : This function is used to Read the CPHS ONS file EF_ONS. */ GLOBAL BOOL cmhSIM_ONS_Update (int ref, T_SIM_FILE_UPDATE_IND *fu) { BOOL found = FALSE; UBYTE i; TRACE_FUNCTION ("cmhSIM_ONS_Update()"); for (i = 0; i < (int)fu->val_nr; i++) { if (fu->file_info[i].v_path_info EQ TRUE AND fu->file_info[i].path_info.df_level1 EQ SIM_DF_GSM AND fu->file_info[i].path_info.v_df_level2 EQ FALSE AND fu->file_info[i].datafield EQ SIM_CPHS_ONSTR) { found = TRUE; break; } } if (found) { cmhMM_ONSReadName(); simShrdPrm.fuRef = (UBYTE)ref; return FALSE; /* reading files */ } else { return TRUE; /* nothing to do */ } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_Get_CSP | +--------------------------------------------------------------------+ PURPOSE : This function is used to request the SIM CPHS file */ GLOBAL void cmhSIM_Get_CSP() { TRACE_FUNCTION ("cmhSIM_Get_CSP()"); cmhSIM_ReadTranspEF( CMD_SRC_NONE, AT_CMD_NONE, FALSE, NULL, SIM_CPHS_CINF, 0, ACI_CPHS_INFO_SIZE, NULL, cmhSIM_Get_CSP_cb ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_Get_CSP_cb | +--------------------------------------------------------------------+ PURPOSE : Call back for SIM read for CPHS. */ void cmhSIM_Get_CSP_cb(SHORT table_id) { TRACE_FUNCTION ("cmhSIM_Get_CSP_cb()"); simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; /* Step #1: Reading of CPHS Info */ if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR OR simShrdPrm.atb[table_id].exchData EQ NULL OR simShrdPrm.atb[table_id].dataLen < ACI_CPHS_INFO_SIZE ) { ; /* CPHS info not supported or invalid */ } else if ((simShrdPrm.atb[table_id].exchData[1] & 0x03) EQ ALLOCATED_AND_ACTIVATED) { /* continue with reading of CSP file */ cmhSIM_Read_CSP(); return; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_AD_Update | +--------------------------------------------------------------------+ PURPOSE : This function is used to request the SIM Customer Service Profile (EF_CPHS_CSP). */ GLOBAL BOOL cmhSIM_CSP_Update (int ref, T_SIM_FILE_UPDATE_IND *fu) { /* Implements Measure 42 */ return ( cmhSIM_AD_CSP_Update( ref, fu, SIM_CPHS_CSP ) ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_Read_CSP | +--------------------------------------------------------------------+ PURPOSE : This function is used to request the SIM Customer Service Profile (EF_CSP). */ GLOBAL void cmhSIM_Read_CSP() { TRACE_FUNCTION ("cmhSIM_Read_CSP()"); cmhSIM_ReadTranspEF( CMD_SRC_NONE, AT_CMD_NONE, FALSE, NULL, SIM_CPHS_CSP, 0, 0, NULL, cmhSIM_Read_CSP_cb ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_Read_CSP_cb | +--------------------------------------------------------------------+ PURPOSE : Call back for SIM read (EF_CSP). */ void cmhSIM_Read_CSP_cb(SHORT table_id) { TRACE_FUNCTION ("cmhSIM_Read_CSP_cb()"); if ( simShrdPrm.atb[table_id].reqDataFld EQ SIM_CPHS_CSP ) { if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR ) { if(simShrdPrm.atb[table_id].dataLen >= ACI_CPHS_CSP_SIZE) { USHORT idx; for(idx=0; idx < simShrdPrm.atb[table_id].dataLen; idx = idx+2) { if(simShrdPrm.atb[table_id].exchData[idx] EQ VAS_SERVICE_GROUP_CODE) { if(simShrdPrm.atb[table_id].exchData[idx+1] & PLMN_MODE_BIT_ON) { simShrdPrm.PLMN_Mode_Bit = CPHS_CSP_PLMN_MODE_BIT_ON; } else { simShrdPrm.PLMN_Mode_Bit = CPHS_CSP_PLMN_MODE_BIT_OFF; } break; } } } } #ifdef SIM_TOOLKIT if (simShrdPrm.fuRef >= 0) { psaSAT_FUConfirm (simShrdPrm.fuRef, (USHORT)((simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR)? SIM_FU_SUCCESS: SIM_FU_ERROR)); } #endif } simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; } #ifdef SIM_PERS_OTA /* +------------------------------------------------------------------------------ | Function : cmhSIM_Register_Read_DCK +------------------------------------------------------------------------------ | Description : This function is used to request the SIM De-personalization Control Keys | (EF_DCK) | Parameters : ref - Reference for file update | *fu - Pointer to T_SIM_FILE_UPDATE_IND | | Return : TRUE if no files left to read, | FALSE if some files are there to read | +------------------------------------------------------------------------------ */ GLOBAL BOOL cmhSIM_Register_Read_DCK (int ref, T_SIM_FILE_UPDATE_IND *fu) { UBYTE i; TRACE_FUNCTION ("cmhSIM_Register_Read_DCK()"); for (i = 0; i < (int)fu->val_nr AND (fu->file_info[i].datafield NEQ SIM_DCK); i++) { } if (i NEQ (int)fu->val_nr ) { if (psaSIM_ChkSIMSrvSup(SRV_DePersCK)) { TRACE_FUNCTION("SRV_DePersCK supported."); cmhSIM_ReadTranspEF( CMD_SRC_NONE, AT_CMD_NONE, FALSE, NULL, SIM_DCK, 0, 16, NULL, cmhSIM_Read_DCK_cb ); } simShrdPrm.fuRef = (UBYTE)ref; return FALSE; /* reading files */ } else { return TRUE; /* nothing to do */ } } /* +------------------------------------------------------------------------------ | Function : cmhSIM_Read_DCK_cb +------------------------------------------------------------------------------ | Description : Call back for SIM read (EF_DCK). | Parameters : SHORT table_id | | Return : void | +------------------------------------------------------------------------------ */ void cmhSIM_Read_DCK_cb(SHORT table_id) { TRACE_FUNCTION ("cmhSIM_Read_DCK_cb()"); if ( simShrdPrm.atb[table_id].reqDataFld EQ SIM_DCK ) { if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR ) { aci_slock_psaSIM_decodeIMSI_without_parity (&simShrdPrm.atb[table_id].exchData[0], 8, (char *) nw_ctrl_key); aci_slock_psaSIM_decodeIMSI_without_parity (&simShrdPrm.atb[table_id].exchData[4], 8, (char *) nw_subset_ctrl_key); aci_slock_psaSIM_decodeIMSI_without_parity (&simShrdPrm.atb[table_id].exchData[8], 8, (char *) sp_ctrl_key); aci_slock_psaSIM_decodeIMSI_without_parity (&simShrdPrm.atb[table_id].exchData[12], 8, (char *) corp_ctrl_key); aci_slock_unlock(SIMLOCK_NETWORK, (char *) nw_ctrl_key); aci_slock_unlock(SIMLOCK_NETWORK_SUBSET, (char *) nw_subset_ctrl_key); aci_slock_unlock(SIMLOCK_SERVICE_PROVIDER, (char *) sp_ctrl_key); aci_slock_unlock(SIMLOCK_CORPORATE, (char *) corp_ctrl_key); cmhSIM_WriteDefaultValue_DCK(); } } } /* +------------------------------------------------------------------------------ | Function : cmhSIM_WriteDefaultValue_DCK +------------------------------------------------------------------------------ | Description : This function is used to write back the SIM De-personalization Control Keys | (EF_DCK) read during init after depersonalizing the ME | | Parameters : none | | Return : void | +------------------------------------------------------------------------------ */ GLOBAL void cmhSIM_WriteDefaultValue_DCK() { UBYTE all_keys[MAX_DCK_LEN]; TRACE_FUNCTION ("cmhSIM_WriteDefaultValue_DCK()"); memset(all_keys,NOT_PRESENT_8BIT,MAX_DCK_LEN); cmhSIM_WriteTranspEF( CMD_SRC_NONE, AT_CMD_NONE, FALSE, NULL, SIM_DCK, 0, MAX_DCK_LEN, all_keys , NULL ); } #endif /* SIM_PERS_OTA */ #ifdef SIM_PERS /* +------------------------------------------------------------------------------ | Function : cmhSIM_UnlockTimeout +------------------------------------------------------------------------------ | Description : This function handles the Penalty timout. | | Parameters : none | | Return : void | +------------------------------------------------------------------------------ */ GLOBAL void cmhSIM_UnlockTimeout(void) { aci_slock_unlock_timer_stopped(); } #endif #ifdef FF_CPHS_REL4 /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_WrCfis | +--------------------------------------------------------------------+ PURPOSE : Writing data to EF-CFIS in SIM */ GLOBAL T_ACI_RETURN cmhSIM_WrCfis (T_ACI_CMD_SRC srcId, T_ACI_CFIS_MOD mode, UBYTE index, UBYTE mspId, UBYTE cfuStat,CHAR* number, T_ACI_TOA* type, UBYTE cc2_id) { T_ACI_RETURN ret = AT_FAIL; /* data send to SIM */ UBYTE *exchData ; T_ACI_TOA toa_type; TRACE_FUNCTION ("cmhSIM_WrCfis()"); MALLOC (exchData,ACI_SIZE_EF_CFIS); /* reset exchData */ memset(exchData, 0xFF,ACI_SIZE_EF_CFIS ); if( mode EQ CFIS_MOD_Write ) { *exchData= mspId; *(exchData+1) = cfuStat; cmhPHB_getAdrBcd ( exchData+4, exchData+2, MAX_PHB_NUM_LEN, number ); if(type NEQ NULL) { memcpy(&toa_type,type,sizeof(toa_type)); } else { toa_type.ton = TON_Unknown; toa_type.npi = NPI_IsdnTelephony; if ( number[0] EQ '+' ) { toa_type.ton = TON_International; } } cmhPHB_toaMrg(&toa_type, exchData+3 ); /* capability/configuration identifier data and EXT identifier data */ *(exchData+14) = cc2_id; *(exchData + 15) = 0xFF; } else { *(exchData+1) = 0x00; } /* write to SIM */ ret = cmhSIM_WriteRecordEF( srcId,AT_CMD_P_CFIS,SIM_CFIS,index, ACI_SIZE_EF_CFIS,exchData, cmhSIM_WrCnfCfis); MFREE(exchData); return ( ret ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_WrMwis | +--------------------------------------------------------------------+ PURPOSE : Writing data to EF-MWIS in SIM */ GLOBAL T_ACI_RETURN cmhSIM_WrMwis (T_ACI_CMD_SRC srcId, T_ACI_MWIS_MOD mode, UBYTE mspId, T_ACI_MWIS_MWI *mwis) { T_ACI_RETURN ret = AT_FAIL; /* data send to SIM */ UBYTE *exchData ; TRACE_FUNCTION ("cmhSIM_WrMwis()"); MALLOC (exchData,ACI_SIZE_EF_MWIS); /* reset exchData */ memset(exchData, 0xFF,ACI_SIZE_EF_MWIS ); if( mode EQ MWIS_MOD_Write ) { *exchData= mwis->mwiStat; *(exchData+1) = mwis->mwis_count_voice; *(exchData+2) = mwis->mwis_count_fax; *(exchData+3) = mwis->mwis_count_email; *(exchData+4) = mwis->mwis_count_other; } else { *exchData = 0x00; } /* write to SIM */ ret = cmhSIM_WriteRecordEF( srcId,AT_CMD_P_MWIS,SIM_MWIS,mspId, ACI_SIZE_EF_MWIS,exchData, cmhSIM_WrCnfMwis); MFREE(exchData); return ( ret ); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-F&D (8411) MODULE : CMH_SIMF | | STATE : code ROUTINE : cmhSIM_WrMbdn | +--------------------------------------------------------------------+ PURPOSE : Writing data to EF-MBDN in SIM */ GLOBAL T_ACI_RETURN cmhSIM_WrMbdn (T_ACI_CMD_SRC srcId, T_ACI_MBN_MODE mode, UBYTE index, CHAR* number, T_ACI_TOA* type, UBYTE cc2_id, T_ACI_PB_TEXT *text) { T_ACI_RETURN ret = AT_FAIL; /* data send to SIM */ UBYTE *exchData; T_ACI_TOA toa_type; UBYTE tag_len = 0; /* Length of Alpha identifier */ UBYTE tag[PHB_MAX_TAG_LEN]; /* Alpha identifier */ TRACE_FUNCTION ("cmhSIM_WrMbdn()"); MALLOC (exchData,ACI_SIZE_EF_MBDN); /* reset exchData */ memset(exchData, 0xFF,ACI_SIZE_EF_MBDN ); if( mode EQ MBN_Mode_Write ) { if (text NEQ NULL) { cmhPHB_getMfwTagSim ( text, (UBYTE*)tag, &tag_len, PHB_MAX_TAG_LEN ); memcpy(exchData, tag, PHB_MAX_TAG_LEN); } /* The number and length has to be stored after the alpha identifier(Max 20 Bytes).Hence start updating the number from the 22nd address location of exchData and similarly for other parameters */ cmhPHB_getAdrBcd ( exchData+22, exchData+20, MAX_MB_NUM_LEN, number ); if(type NEQ NULL) { memcpy(&toa_type,type,sizeof(toa_type)); } else { toa_type.ton = TON_Unknown; toa_type.npi = NPI_IsdnTelephony; if ( number[0] EQ '+' ) { toa_type.ton = TON_International; } } cmhPHB_toaMrg(&toa_type, exchData+21 ); /* capability/configuration identifier data and EXT identifier data */ *(exchData+32) = cc2_id; *(exchData+33) = 0xFF; /* EXT7 identifier is not supported */ } /* write to SIM */ ret = cmhSIM_WriteRecordEF( srcId,AT_CMD_P_MBDN,SIM_MBDN,index, ACI_SIZE_EF_MBDN,exchData, cmhSIM_WrCnfMbdn); MFREE(exchData); return ( ret ); } #endif /* FF_CPHS_REL4 */ /* Implements Measure 120 */ /* +------------------------------------------------------------------------------ | Function : cmhSIM_OpRead_simDataFld_RcdCb +------------------------------------------------------------------------------ | Description : This is CallBack function for SIM retrieval of EF_PNN | or EF_OPL, depending upon which one has been passed as an | argument reqDataFld. | | Parameters : table_id - | reqDataFld - requested datafield identifier | (SIM_PNN or SIM_OPL) | | Return : void +------------------------------------------------------------------------------ */ LOCAL void cmhSIM_OpRead_simDataFld_RcdCb( SHORT table_id, USHORT reqDataFld ) { void (*BuildsimDataFldList)(SHORT); void (*rplyCB)(SHORT); UBYTE *status,*num_rcd, max_records; TRACE_FUNCTION( "cmhSIM_OpRead_simDataFld_RcdCb()" ); if( reqDataFld EQ SIM_PNN ) { BuildsimDataFldList = cmhSIM_BuildPnnList; status = &simShrdPrm.pnn_list.pnn_status; num_rcd = &simShrdPrm.pnn_list.num_rcd; rplyCB = cmhSIM_OpReadPnnRcdCb; max_records = PNN_MAX_RECORDS; } else /* SIM_OPL */ { BuildsimDataFldList = cmhSIM_BuildOPLList; status = &simShrdPrm.opl_list.opl_status; num_rcd = &simShrdPrm.opl_list.num_rcd; rplyCB = cmhSIM_OpReadOplRcdCb; max_records = OPL_MAX_RECORDS; } /* Decode and copy OPL record data to OPL list*/ /*--------------------------------------------*/ if( simShrdPrm.atb[table_id].dataLen AND simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR ) { /* * Here we are calling either cmhSIM_BuildPnnList() * or cmhSIM_BuildOPLList() */ (*BuildsimDataFldList)( table_id ); *status = TRUE; } else { TRACE_EVENT( "Empty record" ); } simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; /* If not last EF record retrieve next record*/ /*-------------------------------------------*/ simShrdPrm.atb[table_id].recNr++; (*num_rcd)++; if ( (*num_rcd) > max_records ) { TRACE_EVENT( "Max records reached" ); } else if(simShrdPrm.atb[table_id].recNr <= simShrdPrm.atb[table_id].recMax ) { TRACE_EVENT_P1("Read next record: %d",simShrdPrm.atb[table_id].recNr); cmhSIM_OpRead_Opl_or_Pnn_Rcd( simShrdPrm.atb[table_id].recNr, reqDataFld, rplyCB); return; } TRACE_EVENT("Retrieval of records finished"); /* continue with next one */ cmhSIM_StartOperatorName(); } /* Implements Measure 42 */ /* +------------------------------------------------------------------------------ | Function : cmhSIM_AD_CSP_Update +------------------------------------------------------------------------------ | Description : This function can be used to request the SIM Customer Service | Profile (EF_CPHS_CSP) or SIM Administrative Data (EF_AD). | by passing appropriate EF as an argument sim_datafld. | | | | Parameters : ref - Reference for File Update | fu - Pointer to SIM_FILE_UPDATE_IND | sim_datafld - EF - (SIM_AD or SIM_CPHS_CSP) | | Return : BOOL - TRUE or FALSE +------------------------------------------------------------------------------ */ LOCAL BOOL cmhSIM_AD_CSP_Update ( int ref, T_SIM_FILE_UPDATE_IND *fu , USHORT sim_datafld ) { BOOL found = FALSE; UBYTE i; TRACE_FUNCTION ( "cmhSIM_AD_CSP_Update()" ); for (i = 0; i < (int)fu->val_nr; i++) { if (!found AND fu->file_info[i].v_path_info EQ TRUE AND fu->file_info[i].path_info.df_level1 EQ SIM_DF_GSM AND fu->file_info[i].path_info.v_df_level2 EQ FALSE AND fu->file_info[i].datafield EQ sim_datafld) { found = TRUE; } } if (found) { if ( sim_datafld EQ SIM_AD ) { cmhSIM_Read_AD(); } else { cmhSIM_Read_CSP(); } simShrdPrm.fuRef = (UBYTE)ref; return FALSE; /* reading files */ } else { return TRUE; /* nothing to do */ } } /* +------------------------------------------------------------------------------ | Function : cmhSIM_Req_or_Write_PlmnSel +------------------------------------------------------------------------------ | Description : This function can be used for Either Reading or Writing | the EF PLMN SEL from SIM | | Parameters : sercId - AT command source identifier | accType - Access Type | (ACT_WR_DAT or ACT_RD_DAT ) | | Return : ACI functional return codes +------------------------------------------------------------------------------ */ GLOBAL T_ACI_RETURN cmhSIM_Req_or_Write_PlmnSel ( T_ACI_CMD_SRC srcId, T_SIM_ACTP accType ) { T_ACI_RETURN ret = AT_FAIL; SHORT table_id; TRACE_FUNCTION ("cmhSIM_Req_or_Write_PlmnSel()"); /* *----------------------------------------------------------------- * request table id for SIM SAP access *----------------------------------------------------------------- */ table_id = psaSIM_atbNewEntry(); if(table_id NEQ NO_ENTRY) { if( accType EQ ACT_WR_DAT ) { simShrdPrm.atb[table_id].dataLen = CPOLSimEfDataLen; simShrdPrm.atb[table_id].recMax = NOT_PRESENT_8BIT; simShrdPrm.atb[table_id].rplyCB = cmhSIM_WrCnfPlmnSel; } else /* ACT_RD_DAT */ { simShrdPrm.atb[table_id].dataLen = NOT_PRESENT_8BIT; simShrdPrm.atb[table_id].recMax = ACI_LEN_PLMN_SEL_FLD; simShrdPrm.atb[table_id].rplyCB = cmhSIM_RdCnfPlmnSel; } simShrdPrm.atb[table_id].accType = accType; simShrdPrm.atb[table_id].v_path_info = FALSE; simShrdPrm.atb[table_id].reqDataFld = SIM_PLMNSEL; simShrdPrm.atb[table_id].dataOff = 0; simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; simShrdPrm.atb[table_id].exchData = CPOLSimEfData; simShrdPrm.aId = table_id; simEntStat.curCmd = AT_CMD_CPOL; simShrdPrm.owner = (T_OWN)srcId; simEntStat.entOwn = srcId; if(psaSIM_AccessSIMData() < 0) { TRACE_EVENT("FATAL ERROR psaSIM in +CPOL"); ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); } else { ret = AT_EXCT; } } return ( ret ); } /* +------------------------------------------------------------------------------ | Function : cmhSIM_ReqLanguage_LP_or_ELP +------------------------------------------------------------------------------ | Description : This function can be used for Reading the ELP or LP field | of the SIM | | Parameters : sercId - AT command source identifier | reqDataFld - SIM_ELP or SIM_LP | | Return : ACI functional return codes +------------------------------------------------------------------------------ */ GLOBAL T_ACI_RETURN cmhSIM_ReqLanguage_LP_or_ELP ( T_ACI_CMD_SRC srcId, USHORT reqDataFld ) { T_ACI_RETURN ret = AT_FAIL; SHORT table_id; TRACE_FUNCTION ("cmhSIM_ReqLanguage_LP_or_ELP()"); /* *----------------------------------------------------------------- * request table id for SIM SAP access *----------------------------------------------------------------- */ table_id = psaSIM_atbNewEntry(); if(table_id NEQ NO_ENTRY) { simShrdPrm.atb[table_id].reqDataFld = reqDataFld; if(reqDataFld EQ SIM_ELP ) { simShrdPrm.atb[table_id].recMax = ACI_LEN_LAN_FLD; simShrdPrm.atb[table_id].exchData = CLANSimEfData; simShrdPrm.atb[table_id].rplyCB = cmhSIM_RdCnfLangELP; } else /* SIM_LP */ { simShrdPrm.atb[table_id].recMax = ACI_MAX_LAN_LP_NTRY; simShrdPrm.atb[table_id].exchData = CLANSimEfDataLP; simShrdPrm.atb[table_id].rplyCB = cmhSIM_RdCnfLangLP; } simShrdPrm.atb[table_id].v_path_info = FALSE; simShrdPrm.atb[table_id].accType = ACT_RD_DAT; simShrdPrm.atb[table_id].dataOff = 0; /* length is variable */ simShrdPrm.atb[table_id].dataLen = NOT_PRESENT_8BIT; simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; simShrdPrm.aId = table_id; simEntStat.curCmd = AT_CMD_CLAN; simShrdPrm.owner = (T_OWN)srcId; simEntStat.entOwn = srcId; if(psaSIM_AccessSIMData() < 0) { TRACE_EVENT("FATAL ERROR psaSIM in +CLAN"); ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); } else { ret = AT_EXCT; } } return ( ret ); } /* +------------------------------------------------------------------------------ | Function : cmhSIM_OpRead_Opl_or_Pnn_Rcd +------------------------------------------------------------------------------ | Description : This function can be used for Reading the SIM_OPL or SIM_PNN | field of the SIM | | Parameters : rcd - Record Number | reqDataFld - SIM_OPL or SIM_PNN | rplyCB - Call Back Function | | Return : BOOL - TRUE or FALSE +------------------------------------------------------------------------------ */ LOCAL BOOL cmhSIM_OpRead_Opl_or_Pnn_Rcd( UBYTE rcd, USHORT reqDataFld, void (*rplyCB)(SHORT) ) { SHORT table_id; TRACE_FUNCTION ("cmhSIM_OpRead_Opl_or_Pnn_Rcd()"); table_id = psaSIM_atbNewEntry(); if(table_id NEQ NO_ENTRY) { simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; simShrdPrm.atb[table_id].accType = ACT_RD_REC; simShrdPrm.atb[table_id].v_path_info = FALSE; simShrdPrm.atb[table_id].reqDataFld = reqDataFld; simShrdPrm.atb[table_id].dataOff = 0; simShrdPrm.atb[table_id].recNr = rcd; simShrdPrm.atb[table_id].recMax = 0; simShrdPrm.atb[table_id].exchData = NULL; simShrdPrm.atb[table_id].dataLen = NOT_PRESENT_8BIT; simShrdPrm.atb[table_id].rplyCB = rplyCB; simShrdPrm.aId = table_id; if(psaSIM_AccessSIMData() < 0) { TRACE_EVENT("FATAL ERROR"); return FALSE; } return TRUE; } return TRUE; } /* +------------------------------------------------------------------------------ | Function : cmhSIM_ReqLanguage_LP_or_ELP +------------------------------------------------------------------------------ | Description : This function can be used for Reading or Writing the | Transparent EF of the SIM | | Parameters : srcId - AT command source identifier | cmd - AT command identifier | datafield - Requested datafield identifier | offset - DataField Offset | dataLen - Data Length | exchData - points to exchange data buffer | rplyCB - points to reply call-back | accType - Type of access (Read or Write) | | Return : BOOL - TRUE or FALSE +------------------------------------------------------------------------------ */ LOCAL T_ACI_RETURN cmhSIM_Write_or_Read_TranspEF (T_ACI_CMD_SRC srcId, T_ACI_AT_CMD cmd, USHORT datafield, USHORT offset, UBYTE datalen, UBYTE * exchData, void (*rplyCB)(SHORT), T_SIM_ACTP accType, BOOL v_path_info, T_path_info *path_info_ptr) { T_ACI_RETURN ret = AT_FAIL; SHORT table_id; TRACE_FUNCTION ("cmhSIM_Write_or_Read_TranspEF()"); /* *----------------------------------------------------------------- * request table id for SIM SAP access *----------------------------------------------------------------- */ table_id = psaSIM_atbNewEntry(); if(table_id NEQ NO_ENTRY) { simShrdPrm.atb[table_id].accType = accType; simShrdPrm.atb[table_id].v_path_info = v_path_info; if(v_path_info EQ TRUE) { simShrdPrm.atb[table_id].path_info.df_level1 = path_info_ptr->df_level1; simShrdPrm.atb[table_id].path_info.v_df_level2 = path_info_ptr->v_df_level2; if(path_info_ptr->v_df_level2 EQ TRUE) { simShrdPrm.atb[table_id].path_info.df_level2 = path_info_ptr->df_level2; } } simShrdPrm.atb[table_id].reqDataFld = datafield; simShrdPrm.atb[table_id].dataOff = offset; simShrdPrm.atb[table_id].recNr = 0; if(accType EQ ACT_WR_DAT) { simShrdPrm.atb[table_id].dataLen = datalen; simShrdPrm.atb[table_id].recMax = NOT_PRESENT_8BIT; } else { simShrdPrm.atb[table_id].dataLen = NOT_PRESENT_8BIT; simShrdPrm.atb[table_id].recMax = datalen; } simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; simShrdPrm.atb[table_id].exchData = exchData; simShrdPrm.atb[table_id].rplyCB = rplyCB; simShrdPrm.aId = table_id; if (srcId NEQ CMD_SRC_NONE) { simEntStat.curCmd = cmd; simShrdPrm.owner = (T_OWN)srcId; simEntStat.entOwn = srcId; } if(psaSIM_AccessSIMData() < 0) { TRACE_EVENT("FATAL ERROR psaSIM"); ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); } else { ret = AT_EXCT; } } return ( ret ); } /* +------------------------------------------------------------------------------ | Function : cmhSIM_Write_or_Read_RecordEF +------------------------------------------------------------------------------ | Description : This function can be used for Reading or Writing the | EF of the SIM | | Parameters : srcId - AT command source identifier | cmd - AT command identifier | datafield - Requested datafield identifier | offset - DataField Offset | dataLen - Data Length | exchData - points to exchange data buffer | rplyCB - points to reply call-back | accType - Type of access (Read or Write) | | Return : BOOL - TRUE or FALSE +------------------------------------------------------------------------------ */ LOCAL T_ACI_RETURN cmhSIM_Write_or_Read_RecordEF ( T_ACI_CMD_SRC srcId, T_ACI_AT_CMD cmd, USHORT datafield, UBYTE record, UBYTE datalen, UBYTE * exchData, void (*rplyCB)(SHORT), T_SIM_ACTP accType, BOOL v_path_info, T_path_info *path_info_ptr) { T_ACI_RETURN ret = AT_FAIL; SHORT table_id; TRACE_FUNCTION ("cmhSIM_Write_or_Read_RecordEF()"); /* *----------------------------------------------------------------- * request table id for SIM SAP access *----------------------------------------------------------------- */ table_id = psaSIM_atbNewEntry(); if(table_id NEQ NO_ENTRY) { simShrdPrm.atb[table_id].accType = accType; simShrdPrm.atb[table_id].v_path_info = v_path_info; if(v_path_info EQ TRUE) { simShrdPrm.atb[table_id].path_info.df_level1 = path_info_ptr->df_level1; simShrdPrm.atb[table_id].path_info.v_df_level2 = path_info_ptr->v_df_level2; if(path_info_ptr->v_df_level2 EQ TRUE) { simShrdPrm.atb[table_id].path_info.df_level2 = path_info_ptr->df_level2; } } simShrdPrm.atb[table_id].reqDataFld = datafield; simShrdPrm.atb[table_id].dataOff = 0; /* * for CPHS (and this shall probably be extended to other SIM * access operations) dataLen passed in SIM_READ_RECORD_REQ should * be NOT_PRESENT_8BIT (to let the SIM entity handling this length * ACI does not know it anyway...). Yet size of received data should * be checked when conf is received (to avoid crashes with exotic SIM cards */ if(accType EQ ACT_RD_REC) { #ifdef FF_CPHS if(cmd EQ AT_CMD_CPHS) { simShrdPrm.atb[table_id].check_dataLen = TRUE; } #endif /* FF_CPHS */ } simShrdPrm.atb[table_id].dataLen = datalen; simShrdPrm.atb[table_id].recNr = record; simShrdPrm.atb[table_id].recMax = NOT_PRESENT_8BIT; simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; simShrdPrm.atb[table_id].exchData = exchData; simShrdPrm.atb[table_id].rplyCB = rplyCB; simShrdPrm.aId = table_id; if (srcId NEQ CMD_SRC_NONE) { simEntStat.curCmd = cmd; simShrdPrm.owner = (T_OWN)srcId; simEntStat.entOwn = srcId; } if(psaSIM_AccessSIMData() < 0) { TRACE_EVENT("FATAL ERROR psaSIM"); ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); } else { ret = AT_EXCT; } } return ( ret ); } /* +------------------------------------------------------------------------------ | Function : cmhSIM_ReqLanguage_LP_or_ELP +------------------------------------------------------------------------------ | Description : This function starts reading of LP or ELP field from SIM | for SAT feature LS. | | Parameters : reqDataFld - SIM_OPL or SIM_PNN | recMax - Maximum Records. | exchData - points to exchange data buffer | rplyCB - Call Back Function | | Return : BOOL - TRUE or FALSE +------------------------------------------------------------------------------ */ GLOBAL BOOL cmhSIM_ReqLanguagePrf_LP_or_ELP( USHORT reqDataFld, UBYTE recMax, UBYTE *exchData, void (*rplyCB)(SHORT) ) { BOOL ret = FALSE; SHORT table_id; TRACE_FUNCTION ("cmhSIM_ReqLanguagePrf_LP_or_ELP()"); /* *----------------------------------------------------------------- * request table id for SIM SAP access *----------------------------------------------------------------- */ table_id = psaSIM_atbNewEntry(); if(table_id NEQ NO_ENTRY) { simShrdPrm.atb[table_id].accType = ACT_RD_DAT; simShrdPrm.atb[table_id].v_path_info = FALSE; simShrdPrm.atb[table_id].reqDataFld = reqDataFld; simShrdPrm.atb[table_id].dataOff = 0; // length is variable simShrdPrm.atb[table_id].dataLen = NOT_PRESENT_8BIT; simShrdPrm.atb[table_id].recMax = recMax; simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; simShrdPrm.atb[table_id].exchData = exchData; simShrdPrm.atb[table_id].rplyCB = rplyCB; simShrdPrm.aId = table_id; if(psaSIM_AccessSIMData() < 0) { return ( ret ); } else { ret = TRUE; } } return ( ret ); } /*==== EOF ========================================================*/