FreeCalypso > hg > fc-tourmaline
diff src/g23m-gsm/mm/mm_regp.c @ 1:fa8dc04885d8
src/g23m-*: import from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:25:50 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-gsm/mm/mm_regp.c Fri Oct 16 06:25:50 2020 +0000 @@ -0,0 +1,1640 @@ +/* ++----------------------------------------------------------------------------- +| Project : GSM-PS (8410) +| Modul : MM_REGP ++----------------------------------------------------------------------------- +| 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 Modul defines the functions for the registration +| capability of the module Mobility Management. ++----------------------------------------------------------------------------- +*/ + +#ifndef MM_REGP_C +#define MM_REGP_C + +#define ENTITY_MM + +/*==== INCLUDES ===================================================*/ +#if defined (NEW_FRAME) + +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include "typedefs.h" +#include "pcm.h" +#include "pconst.cdg" +#include "mconst.cdg" +#include "message.h" +#include "ccdapi.h" +#include "vsi.h" +#include "custom.h" +#include "gsm.h" +#include "prim.h" +#include "cnf_mm.h" +#include "mon_mm.h" +#include "pei.h" +#include "tok.h" +#include "mm.h" +#include "mm_em.h" + +#else + +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include "stddefs.h" +#include "pcm.h" +#include "pconst.cdg" +#include "mconst.cdg" +#include "message.h" +#include "ccdapi.h" +#include "custom.h" +#include "gsm.h" +#include "prim.h" +#include "cnf_mm.h" +#include "mon_mm.h" +#include "vsi.h" +#include "pei.h" +#include "tok.h" +#include "mm.h" +#include "mm_em.h" + +#endif + +/*==== EXPORT =====================================================*/ + +/*==== VARIABLES ==================================================*/ + +/*==== FUNCTIONS ==================================================*/ + +/*==== PRIVAT =====================================================*/ + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : mm_auto_net_reg | ++--------------------------------------------------------------------+ + + PURPOSE : Register in automatic mode. + +*/ + +GLOBAL void mm_auto_net_reg(void) +{ + GET_INSTANCE_DATA; + T_plmn last_plmn; + + TRACE_FUNCTION("mm_auto_net_reg"); + + last_plmn.v_plmn = V_PLMN_PRES; + memcpy (last_plmn.mcc, mm_data->reg.lai.mcc, SIZE_MCC); + memcpy (last_plmn.mnc, mm_data->reg.lai.mnc, SIZE_MNC); + + /* + * start full PLMN search in automatic mode + */ + mm_data->attempt_cnt = 0; + + mm_data->reg.bcch_encode = + (mm_data->reg.update_stat EQ MS_UPDATED AND !reg_plmn_empty (&last_plmn)); + /* + * It exists an updated last PLMN if bcch_encode is TRUE here + */ + + mm_data->reg.plmn_cnt = 0; /* Delete list of available PLMNs */ + if (mm_data->reg.bcch_encode AND !reg_plmn_equal_hplmn (&last_plmn)) + { + TRACE_EVENT ("Start with LPLMN"); + + /* LPLMN available and not equal HPLMN => start with LPLMN */ + mm_data->reg.actual_plmn = last_plmn; /* Struct copy */ + } + else + { + TRACE_EVENT ("Start with HPLMN"); + + /* LPLMN not available or not updated => start with HPLMN */ + reg_extract_hplmn (&mm_data->reg.actual_plmn); + } + + EM_START_REGISTRATION_AUTO_MODE; + + mm_mmr_reg_req (FUNC_PLMN_SRCH); +} + + +#ifdef GPRS +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_set_gprs_reg_type | ++--------------------------------------------------------------------+ + + PURPOSE : Set the new registration type as delivered by GMM. + This may also affect the CM_GPRS_EST state machine. + +*/ + + +LOCAL void reg_set_gprs_reg_type (UBYTE reg_type) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("reg_set_gprs_reg_type()"); + + switch (reg_type) + { + case REG_GPRS_INACTIVE: + /* CM establishment always allowed if GPRS is not present */ + SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_OK); + break; + + case REG_REMOTE_CONTROLLED: + /* Remote controlled location updating not possible with GSM only */ + assert (GET_STATE (STATE_REG_TYPE) NEQ REG_GPRS_INACTIVE); + + /* During RC for non GPRS only mobile CM services are allowed */ + if (mm_data->gprs.mobile_class NEQ MMGMM_CLASS_CG) + { + SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_OK); + } + break; + + case REG_CELL_SEARCH_ONLY: + if (mm_gsm_alone()) + { + /* CM establishment not allowed anymore if GPRS was switched on */ + SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_IDLE); + } + break; + + default: + TRACE_ERROR (UNEXPECTED_PARAMETER); + return; + } + + /* Remember new MM working type */ + SET_STATE (STATE_REG_TYPE, reg_type); +} +#endif /* GPRS */ + +/*==== VARIABLES ==================================================*/ + +/*==== FUNCTIONS ==================================================*/ + +/* ++----------------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_MM | +| STATE : code ROUTINE : mm_reg_gsm_only_req | ++----------------------------------------------------------------------------+ + + PURPOSE : This function perform registration in GSM mode only. + (What about cell selection only?) ### + +*/ + +LOCAL void mm_reg_gsm_only_req (UBYTE service_mode) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("mm_reg_gsm_only_req()"); + + mm_data->reg.full_service_indicated = FALSE; + + /* + * If SIM is inserted, make it valid for MM if + * IMSI is present and full service required, + * otherwise invalidate SIM for MM + */ + switch (service_mode) + { + case SERVICE_MODE_FULL: + if (mm_data->reg.imsi_struct.v_mid EQ V_MID_PRES) + { + mm_data->reg.op.sim_ins = SIM_INSRT; + mm_data->limited_cause = MMCS_INT_NOT_PRESENT; + } + break; + + case SERVICE_MODE_LIMITED: + if (mm_data->reg.op.sim_ins NEQ SIM_NO_INSRT) + { + mm_data->reg.op.sim_ins = SIM_NO_INSRT; + mm_data->limited_cause = MMCS_SIM_REMOVED; /* MMCS_SIM_INVAL_MMIREQ */ + } + break; + + default: + TRACE_ERROR (UNEXPECTED_PARAMETER); + break; + } + + if (mm_data->reg.op.sim_ins EQ SIM_NO_INSRT) + { + /* + * No valid SIM inserted + */ + mm_data->reg.bcch_encode = FALSE; + mm_data->reg.op.v_op = V_OP_PRES; + mm_data->reg.op.m = M_AUTO; + mm_mmr_reg_req (FUNC_LIM_SERV_ST_SRCH); + } + else + { + /* + * Valid SIM inserted + */ + if (mm_data->reg.op.m EQ M_AUTO) + { + mm_auto_net_reg (); + } + else + { + /* + * PLMN search in manual mode: Request PLMN list from RR + */ + // Patch HM >>> + mm_data->plmn_scan_mmi = TRUE; + // Patch HM <<< + mm_mmr_reg_req (FUNC_NET_SRCH_BY_MMI); + + EM_START_REGISTRATION_MANUAL_MODE; + + } + } +} + +/*==== TEST =====================================================*/ + +/* + * ------------------------------------------------------------------- + * PRIMITIVE Processing functions + * ------------------------------------------------------------------- + */ + +/* ++----------------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_MM | +| STATE : code ROUTINE : mm_func_mmgmm_net_req | ++----------------------------------------------------------------------------+ + + PURPOSE : This function handles the MMGMM_NET_REQ primitive. + MMGMM_NET_REQ is always used to start a network search. + +*/ + +GLOBAL void mm_func_mmgmm_net_req (void) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("mm_func_mmgmm_net_req()"); + + if (mm_data->reg.op.sim_ins EQ SIM_INSRT) + { + /* + * SIM present + */ + switch (GET_STATE (STATE_MM)) + { + case MM_NULL: + /* prepare environement for further processing by RR */ + + mm_data->reg.op.m = MODE_MAN; + reg_clear_plmn (&mm_data->reg.actual_plmn); + + mm_mmr_reg_req (FUNC_PLMN_SRCH); + break; + + default: + mm_mmr_reg_req (FUNC_NET_SRCH_BY_MMI); + break; + } + + EM_START_PLMN_LIST_REQUEST; + + } + else + { + /* + * SIM not present + */ + /*If Dual SIM is supported by MS then initially before SIM activation + Network search should be done.Also, anytime network search is asked for + MM should start with PLMN scan and return proper PLMN list*/ +#ifdef FF_DUAL_SIM + TRACE_EVENT("Dual sim is supported and no sim"); + mm_mmr_reg_req (FUNC_NET_SRCH_BY_MMI); +#else + mm_mmgmm_plmn_ind (MMCS_SIM_REMOVED, NULL); +#endif + } +} + + +/* ++----------------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_MM | +| STATE : code ROUTINE : mm_func_mmgmm_nreg_req | ++----------------------------------------------------------------------------+ + + PURPOSE : This function handles the MMGMM_NREG_REQ primitive. + +*/ + +GLOBAL void mm_func_mmgmm_nreg_req (UBYTE detach_cause, + UBYTE detach_done, + USHORT cs) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("mm_func_mmgmm_nreg_req()"); + + /* + * Parameter check from ACI/GMM + */ +#ifdef GPRS + +#ifdef WIN32 + TRACE_EVENT_P1 ("detach_cause = %02X", detach_cause); + TRACE_EVENT_P1 ("detach_done = %02X", detach_done); + TRACE_EVENT_P1 ("cs = %04X", cs); +#endif /* #ifdef WIN32 */ + + /* Check for correct originating entity */ + assert (GET_CAUSE_ORIGIN_ENTITY (cs) EQ + GMM_ORIGINATING_ENTITY); + + /* Check for correct detach_done parameter */ + assert ((detach_done EQ MMGMM_PERFORM_DETACH) OR + (detach_done EQ MMGMM_DETACH_DONE)); +#else + assert (detach_done EQ MMGMM_PERFORM_DETACH); +#endif /* GPRS */ + + /* Remember that the deregistration was requested by MMI */ + mm_data->nreg_request = TRUE; + + /* Remember the cause of the deregistration */ + mm_data->nreg_cause = detach_cause; + + /* + * Timer T3212 is stopped if the mobile station is deactivated + * (i.e. equipment powered down or SIM removed. + */ + TIMERSTOP (T3212); + mm_data->t3212_timeout = FALSE; + + if (mm_data->reg.op.sim_ins EQ SIM_NO_INSRT) + { + /* + * No valid SIM inserted + */ + switch (detach_cause) + { + case CS_POW_OFF: + case CS_SOFT_OFF: + mm_mmr_nreg_req (detach_cause, detach_done); + break; + + case CS_SIM_REM: + mm_mmgmm_nreg_cnf (detach_cause); /* SIM already removed */ + break; + +#ifdef GPRS + case CS_DISABLE: + mm_mmgmm_nreg_cnf (detach_cause); /* Already detached */ + break; +#endif /* GPRS */ + + default: + TRACE_ERROR (UNEXPECTED_DEFAULT); + break; + } + } + else + { + /* + * Valid SIM inserted + */ + switch (detach_cause) + { + case CS_SIM_REM: + mm_data->limited_cause = MMCS_SIM_REMOVED; /* MMCS_SIM_INVAL_MMIREQ */ + //lint -fallthrough + case CS_POW_OFF: + case CS_SOFT_OFF: + mm_mmr_nreg_req (detach_cause, detach_done); + break; + +#ifdef GPRS + case CS_DISABLE: + /* + * Check deregistration cause from GMM + */ + switch (cs) + { + case GMMCS_IMSI_UNKNOWN: /* #2 */ + case GMMCS_ILLEGAL_MS: /* #3 */ + case GMMCS_ILLEGAL_ME: /* #6 */ + case GMMCS_GSM_GPRS_NOT_ALLOWED: /* #8 */ + case GMMCS_PLMN_NOT_ALLOWED: /* #11 */ + case GMMCS_LA_NOT_ALLOWED: /* #12 */ + case GMMCS_ROAMING_NOT_ALLOWED: /* #13 */ +#ifdef REL99 + case GMMCS_ROAMING_NOT_ALLOWED_WITH_RAU_REJ: /* #13 GPRS RAU rejected*/ + case GMMCS_NO_SUITABLE_CELL_IN_LA: /* #15 GPRS attach rejected*/ + case GMMCS_NO_SUITABLE_CELL_IN_LA_WITH_RAU_REJ: /* #15 GPRS RAU rejected*/ +#endif + mm_network_initiated_detach (cs); + break; + + case GMMCS_GPRS_NOT_ALLOWED: /* #7 */ + /* + * # 7 (GPRS services not allowed) + * The MS shall set the GPRS update status to GU3 + * ROAMING NOT ALLOWED (and shall store it according to + * section 4.1.3.2) and shall delete any P-TMSI, P-TMSI signature, + * RAI and GPRS ciphering key sequence number. The SIM shall be + * considered as invalid for GPRS services until switching off or + * the SIM is removed. The new state is GMM-DEREGISTERED. + * [GSM 04.08 subclause 4.7.3.1.4]. + * + * This is a GPRS only cause. MM starts automatically T3212 + * without the need to receive MMGMM_START_T3212_REQ. + * It is expected that GMM will send a MMGMM_REG_REQ + * (REG_GPRS_INACTIVE) immediately after this to trigger a + * registration attempt. + */ + + /* As this is a GPRS only reason, this should not have any + * impact on the update status of GSM. But T3212 has to be + * started now. + */ + mm_func_mmgmm_start_t3212_req (); + TRACE_EVENT ("No impact on update status"); + mm_mmgmm_nreg_cnf (detach_cause); + break; + + case GMMCS_INT_NOT_PRESENT: + /* + * Start remote controlled IMSI DETACH operation + */ + mm_mmr_nreg_req (detach_cause, detach_done); + break; + + default: + TRACE_EVENT ("No impact on update status and nothing done!"); + mm_mmgmm_nreg_cnf (detach_cause); + break; + } + break; /* CS_DISABLE */ +#endif /* GPRS */ + + default: + TRACE_ERROR (UNEXPECTED_DEFAULT); + break; + } + } + + /* Check HPLMN timer state */ + reg_check_hplmn_tim (mm_data->reg.thplmn); +} + + +/* ++----------------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_MM | +| STATE : code ROUTINE : mm_func_mmgmm_plmn_mode_req | ++----------------------------------------------------------------------------+ + + PURPOSE : This function handles the MMGMM_PLMN_MODE_REQ primitive. + MMGMM_PLMN_MODE_REQ is used to switch between automatic and + manual mode of registration. + +*/ + +GLOBAL void mm_func_mmgmm_plmn_mode_req (UBYTE mode) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("mm_func_mmgmm_plmn_mode_req()"); + +#ifndef NTRACE + switch (mode) + { + case MODE_AUTO: + TRACE_EVENT ("automatic mode"); + break; + + case MODE_MAN: + TRACE_EVENT ("manual mode"); + break; + + default: + TRACE_ERROR (UNEXPECTED_PARAMETER); + break; + } +#endif /* NTRACE */ + + /* + * If SIM is inserted, make it valid for MM if IMSI is present + */ + if (mm_data->reg.imsi_struct.v_mid EQ V_MID_PRES) + { + mm_data->reg.op.sim_ins = SIM_INSRT; + mm_data->limited_cause = MMCS_INT_NOT_PRESENT; + } + + mm_data->reg.op.m = mode; + + switch (GET_STATE (STATE_MM)) + { + case MM_NULL: /* Mobile is off, do nothing */ + break; + + // This is just for issue 15605 should be asap removed by an clearly implemented concept for RR_SYNC interface + case MM_IDLE_NO_IMSI: /* Mobile has no SIM or received e.g. cause MMCS_IMSI_IN_HLR" ... */ + if (mode EQ M_MAN) + mm_data->reg.op.func = FUNC_LIM_SERV_ST_SRCH; + //lint -fallthrough + default: + mm_build_rr_sync_req(MSG_MM_MODE); + break; + } + + /* Check HPLMN timer state */ + reg_check_hplmn_tim (mm_data->reg.thplmn); +} + + +/* ++----------------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_MM | +| STATE : code ROUTINE : mm_func_mmgmm_plmn_res | ++----------------------------------------------------------------------------+ + + PURPOSE : This function handles the MMGMM_PLMN_RES primitive. + MMGMM_PLMN_RES is used to select a PLMN manually after + network search or to select RPLMN at switch on in manual mode + +*/ + +GLOBAL void mm_func_mmgmm_plmn_res (const T_plmn *plmn, + UBYTE reg_type, + UBYTE mobile_class) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("mm_func_mmgmm_plmn_res ()"); + + mm_data->reg.full_service_indicated = FALSE; + +#ifdef GPRS + mm_data->gprs.mobile_class = mobile_class; + + if ((reg_type EQ REG_REMOTE_CONTROLLED) AND + (GET_STATE (STATE_REG_TYPE) EQ REG_REMOTE_CONTROLLED)) + { + /* + * GMM tries to retrigger a remote controlled RC procedure while + * this is already running. MM ignores this and continues updating. + */ + TRACE_EVENT ("No retrigger of RC update"); + return; + } + + reg_set_gprs_reg_type (reg_type); +#endif /* GPRS */ + + if (mm_data->reg.op.sim_ins EQ SIM_INSRT) + { + /* + * A valid SIM is inserted + */ + mm_data->reg.plmn_cnt = 0; /* Delete list of available PLMNs */ + +#ifdef GPRS + switch (reg_type) + { + case REG_GPRS_INACTIVE: + case REG_CELL_SEARCH_ONLY: + reg_select_network(plmn); + break; + + case REG_REMOTE_CONTROLLED: + { + /* + * First, we check whether GMM sent a correct PLMN. + * All other cases are a protocol failure and MM cannot do much. + */ + T_plmn camped_plmn; + + camped_plmn.v_plmn = V_PLMN_PRES; + memcpy (camped_plmn.mcc, mm_data->mm.lai.mcc, SIZE_MCC); + memcpy (camped_plmn.mnc, mm_data->mm.lai.mnc, SIZE_MNC); + + assert (reg_plmn_equal_sim (&camped_plmn, plmn)); + } + + /* Perform a remote controlled location updating procedure */ + mm_gprs_update_req (); + break; + + default: + TRACE_ERROR (UNEXPECTED_DEFAULT); + break; + } +#else + reg_select_network(plmn); +#endif /* GPRS */ + } + else + { + /* + * No valid SIM inserted, selection a network manually makes no sense. + */ + mm_func_mmgmm_reg_req (SERVICE_MODE_FULL, reg_type, MMGMM_CLASS_CC, NORMAL_REG); + } +} + + +/* ++----------------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_MM | +| STATE : code ROUTINE : mm_func_mmgmm_reg_req | ++----------------------------------------------------------------------------+ + + PURPOSE : This function handles the MMGMM_REG_REQ primitive, + but it is the functional interface. + +*/ + +GLOBAL void mm_func_mmgmm_reg_req (UBYTE service_mode, + UBYTE reg_type, + UBYTE mobile_class, + UBYTE bootup_act) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("mm_func_mmgmm_reg_req()"); + +#ifdef TRACE_FUNC +/* Implements Measure#32: Row 158 & 159 */ + TRACE_EVENT_P1 (" service_mode = %d", service_mode); + TRACE_EVENT_P1 (" reg_type = %d", reg_type); +#endif + + /* Changes for Boot Time Speedup. MM will get dummy REG_REQ indicating QUICK_REG. In this case + * MM has to send RR_ACTIVATE_REQ with op.func = FUNC_ST_PWR_SCAN. No need to process this as + * it is dummy request and MM will get other REG_REQ indicating NORMAL_REG + */ + if (bootup_act EQ QUICK_REG) + { + mm_data->reg.op.v_op = V_OP_PRES; + mm_data->reg.op.func = FUNC_ST_PWR_SCAN; + mm_rr_act_req (); + return ; + } + /* + * Check incoming parameters from GMM + */ + assert (service_mode EQ SERVICE_MODE_LIMITED OR + service_mode EQ SERVICE_MODE_FULL); + + mm_data->reg.full_service_indicated = FALSE; + +#ifdef GPRS + + mm_data->gprs.mobile_class = mobile_class; + + if ((reg_type EQ REG_REMOTE_CONTROLLED) AND + (GET_STATE (STATE_REG_TYPE) EQ REG_REMOTE_CONTROLLED)) + { + /* + * GMM tries to retrigger a remote controlled RC procedure while + * this is already running. MM ignores this and continues updating. + */ + TRACE_EVENT ("No retrigger of RC update"); + return; + } + + reg_set_gprs_reg_type (reg_type); + + switch (reg_type) + { + case REG_CELL_SEARCH_ONLY: + case REG_GPRS_INACTIVE: + mm_reg_gsm_only_req (service_mode); + break; + + case REG_REMOTE_CONTROLLED: + /* + * This is the request not to start a cell selection but to perform a + * remote controlled location update procedure for GSM. + */ + + if (mm_data->gprs.sim_physically_removed) + { + mm_sim_removed_gprs_active (); + return; + } + + /* Actually start the location updating procedure */ + mm_gprs_update_req(); + break; + + default: + TRACE_ERROR (UNEXPECTED_PARAMETER); + break; + } +#else + mm_reg_gsm_only_req (service_mode); +#endif /* GPRS */ +} + + +#ifndef GPRS +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_mmr_net_req | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive MMR_NET_REQ. + +*/ + +GLOBAL void reg_mmr_net_req (T_MMR_NET_REQ * mmr_net_req) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("reg_mmr_net_req()"); + + /* Mark the network search as beeing for the MMI */ + mm_data->plmn_scan_mmi = TRUE; + + /* Start scanning for available PLMNs */ + mm_func_mmgmm_net_req (); + + PFREE (mmr_net_req); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_mmr_nreg_req | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive MMR_NREG_REQ. + +*/ + +GLOBAL void reg_mmr_nreg_req (T_MMR_NREG_REQ *mmr_nreg_req) +{ + TRACE_FUNCTION ("reg_mmr_nreg_req()"); + + /* Use internal functional interface, set GSM only default parameters */ + mm_func_mmgmm_nreg_req (mmr_nreg_req->detach_cause, + MMGMM_PERFORM_DETACH, + MMGMM_NO_ERROR); + + PFREE (mmr_nreg_req); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_mmr_plmn_mode_req | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive MMR_PLMN_MODE_REQ + +*/ + +GLOBAL void reg_mmr_plmn_mode_req (T_MMR_PLMN_MODE_REQ *plmn_mode_req) +{ + TRACE_FUNCTION ("reg_mmr_plmn_mode_req()"); + + /* Use internal functional interface */ + mm_func_mmgmm_plmn_mode_req (plmn_mode_req->mode); + + EM_SET_PLMN_SEARCH_MODE; + PFREE (plmn_mode_req); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_mmr_plmn_res | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive MMR_PLMN_RES. + +*/ + +GLOBAL void reg_mmr_plmn_res (T_MMR_PLMN_RES *mmr_plmn_res) +{ + TRACE_FUNCTION ("reg_mmr_plmn_res()"); + + /* Use internal functional interface */ + mm_func_mmgmm_plmn_res (&mmr_plmn_res->plmn, + REG_GPRS_INACTIVE, + MMGMM_CLASS_CC); + + PFREE (mmr_plmn_res); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_mmr_reg_req | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive MMR_REG_REQ. + +*/ + +GLOBAL void reg_mmr_reg_req (T_MMR_REG_REQ *mmr_reg_req) +{ + TRACE_FUNCTION ("reg_mmr_reg_req()"); + + /* Use internal functional interface */ + mm_func_mmgmm_reg_req (mmr_reg_req->service_mode, + REG_GPRS_INACTIVE, + MMGMM_CLASS_CC, + mmr_reg_req->bootup_act); + + PFREE (mmr_reg_req); +} +#endif /* GPRS */ + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_sim_auth_cnf | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive SIM_AUTHENTICATION_CNF. + +*/ + +GLOBAL void reg_sim_auth_cnf (T_SIM_AUTHENTICATION_CNF *sim_auth_cnf) +{ + TRACE_FUNCTION ("reg_sim_auth_cnf()"); + + mm_mmr_auth_cnf (sim_auth_cnf); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_sim_mm_insert_ind | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive SIM_MM_INSERT. + +*/ + +GLOBAL void reg_sim_mm_insert_ind (T_SIM_MM_INSERT_IND *sim_mm_insert_ind) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("reg_sim_mm_insert()"); + +#ifdef GPRS + mm_data->gprs.sim_physically_removed = FALSE; +#endif /* #ifdef GPRS */ + + /*SIM_SYNC_REQ to be sent after reading EFs*/ + mm_data->reg.sim_sync_req_pending = TRUE; + + if (mm_data->reg.op.sim_ins EQ SIM_NO_INSRT) + { + /* + * No SIM card was inserted, now it is in and the coresponding handling should happen. + */ + reg_copy_sim_data (sim_mm_insert_ind); + + EM_SIM_INSERT; + + PFREE (sim_mm_insert_ind); + } + else + { + /* + * This happens by SAT activity while SIM is inserted + */ + T_imsi_struct new_imsi_struct; + + reg_read_imsi(&new_imsi_struct, &sim_mm_insert_ind->imsi_field); + + if (! reg_imsi_equal(&new_imsi_struct, &mm_data->reg.imsi_struct)) + { + /* + * IMSI changed. MM Restart procedure, GSM 03.22 subclause 4.10: + * "To perform the procedure the MS shall behave as if + * the SIM is removed and afterwards a new SIM is inserted" + */ + + /* + * Remember the primitive data. Value sim_mm_insert_info NEQ NULL means + * the MM Restart procedure is active. All actions normally performed + * if SIM inserted will be done after RR_ABORT_IND, RR_RELEASE_IND or + * T3220 timeout received or immediately in mm_mmr_nreg_req(). + */ + if (mm_data->reg.sim_insert_info NEQ NULL) + PFREE (mm_data->reg.sim_insert_info); /* Not expected to happen */ + mm_data->reg.sim_insert_info = sim_mm_insert_ind; + + mm_mmr_nreg_req (CS_SIM_REM, MMGMM_PERFORM_DETACH); + if (mm_data->reg.sim_insert_info NEQ NULL) + { + /* + * SIM insert not already performed. e.g. IMSI detach running. + * Clear the registration data, but remember the pointer to the + * new SIM data, the registration mode and the actual plmn. + * sim_sync_req_pending which gets reset in reg_init() is set + * back to TRUE + */ + T_plmn old_plmn; + UBYTE old_mode; + + old_mode = mm_data->reg.op.m; + old_plmn = mm_data->reg.actual_plmn; /* Structure copy */ + reg_init (); + mm_data->reg.sim_insert_info = sim_mm_insert_ind; + mm_data->reg.op.m = old_mode; + mm_data->reg.actual_plmn = old_plmn; + mm_data->reg.sim_sync_req_pending = TRUE; + + } + + EM_SIM_INSERT; + + } + else + { + /* + * IMSI not changed + */ + USHORT old_acc_class; + UBYTE old_thplmn; + + old_acc_class = mm_data->reg.acc_class; + old_thplmn = mm_data->reg.thplmn; + + reg_copy_sim_data (sim_mm_insert_ind); + + if (old_acc_class NEQ mm_data->reg.acc_class) + { + mm_build_rr_sync_req_cause (SYNCCS_ACCC); + } + + if (old_thplmn NEQ mm_data->reg.thplmn) + { + reg_stop_hplmn_tim (); + reg_check_hplmn_tim (mm_data->reg.thplmn); + } + + PFREE (sim_mm_insert_ind); + } + } + check_if_cingular_sim(); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_sim_mm_info_ind | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive SIM_MM_INFO_IND. + +*/ + +GLOBAL void reg_sim_mm_info_ind (T_SIM_MM_INFO_IND *sim_mm_info_ind) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("reg_sim_mm_info_ind()"); + + switch(sim_mm_info_ind->datafield) + { +#ifdef REL99 + case SIM_UCPS_ACTEC: + mm_data->reg.upd_sim_ucps_at = SAT_READ_FILE; + mm_data->reg.sim_ucps_at_len = NOT_PRESENT_16BIT; + /* + * If EFPLMNwAcT is changed, MM must have to re-read EFOPLMNwAcT to + * make a complete list of pref_plmn. + */ + mm_data->reg.upd_sim_ocps_at = SAT_READ_FILE; + mm_data->reg.sim_ocps_at_len = NOT_PRESENT_16BIT; + /* + * Read indicated EF in SIM_MM_INFO_IND from SIM. + */ + /*Set indicatort sim reading is in progress to true*/ + mm_data->reg.sim_read_in_progress = TRUE; + reg_read_next_sim_file(); + break; +#endif + + case SIM_PLMNSEL: +#ifdef REL99 + if (mm_data->reg.sim_uocps_at_used EQ FALSE) +#endif + { + mm_data->reg.upd_sim_plmnsel = SAT_READ_FILE; + mm_data->reg.sim_plmnsel_len = NOT_PRESENT_16BIT; + + /*Set indicatort sim reading is in progress to true*/ + mm_data->reg.sim_read_in_progress = TRUE; + + /* + * Read indicated EF in SIM_MM_INFO_IND from SIM. + */ + reg_read_next_sim_file(); + } + break; + + default: + break; + } + + if(GET_STATE (STATE_MM) == MM_IDLE_NORMAL_SERVICE) + { + reg_check_hplmn_tim(mm_data->reg.thplmn); + } + PFREE (sim_mm_info_ind); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_sim_remove_ind | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive SIM_REMOVE_IND. + +*/ + +GLOBAL void reg_sim_remove_ind (T_SIM_REMOVE_IND *sim_remove_ind) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("reg_sim_remove_ind()"); + + mm_data->limited_cause = MMCS_SIM_REMOVED; /* MMCS_SIM_INVAL_REMOVED */ + + // Better now instead after cause concept implementation in SIM also: + // mm_data->limited_cause = sim_remove_ind->cause; + // + // Problem: None. But this affects not only the MM testcases, but + // also ACI code. And as of the time of this writing it's a too + // big risk to incorporate this in both entities. By the way, + // also GMM should be enhanced in the future and at least a comment + // incorporated in the respective SAPs that also SIM causes are transported. + + if (mm_data->reg.sim_insert_info NEQ NULL) + { + /* + * Pending MM RESTART procedure and now the SIM is physically removed. + * Forget about the MM RESTART procedure. + */ + PFREE (mm_data->reg.sim_insert_info); + mm_data->reg.sim_insert_info = NULL; + } + + if (mm_gsm_alone()) + { + /* + * Clear SIM data for lower layer, start IMSI Detach, + * indicate limited service etc. + */ + if (mm_data->reg.op.sim_ins EQ SIM_INSRT) + mm_mmr_nreg_req (CS_SIM_REM, MMGMM_PERFORM_DETACH); + reg_init (); + } +#ifdef GPRS + else + { + /* Remember there was a physical SIM removal */ + mm_data->gprs.sim_physically_removed = TRUE; + + /* Commenting the OMAPS00048777 changes as it was a incomplete workaround. + Refer the analysis section of the defect 71208 for details */ + +/* if(GET_STATE (STATE_MM) NEQ MM_CONN_ACTIVE) + {*/ + mm_sim_removed_gprs_active (); +/* }*/ + + /* + * Possible IMSI DETACH and entering of MM_IDLE_NO_IMSI state will happen + * after GMM sends + * MMGMM_NREG_REQ (CS_SIM_REM, MMGMM_PERFORM_DETACH/MMGMM_DETACH_DONE). + * Here no IMSI DETACH and invalidation of SIM data can be done as a + * combined attach maybe performed in network mode I. + */ + } +#endif /* GPRS */ + + EM_SIM_REMOVE; + + /* Debug hack. If they have a SIM driver problem, we hopefully will see it */ + mm_data->mm_idle_no_imsi_marker = 128; + PFREE (sim_remove_ind); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_sim_sync_cnf | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive SIM_SYNC_CNF. + +*/ + +GLOBAL void reg_sim_sync_cnf (T_SIM_SYNC_CNF *sim_sync_cnf) +{ + TRACE_FUNCTION ("reg_sim_sync_cnf()"); + + /*Nothing to be done. Just free the primitive to avoid memory leaks*/ + PFREE(sim_sync_cnf); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_sim_file_update_ind | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive SIM_FILE_UPDATE_IND. + The worst case which may by caused by this primitive + is a RR_ACTIVATE_REQ to inform RR about a changed + HPLMN search period or a changed access class. + It is guaranteed by GSM 11.14 subclause 6.4.7.1 + that here no field is changed which causes MM Restart procedure. + + +*/ +GLOBAL void reg_sim_file_upd_ind (T_SIM_FILE_UPDATE_IND *file_upd) +{ + GET_INSTANCE_DATA; + USHORT i; + + TRACE_FUNCTION ("reg_sim_file_upd_ind()"); + /* + * This flag is required to prevent MM to send Acknowledge completion of file update + * if file reading was because of SIM_MM_INSERT_IND/SIM_MM_INFO_IND. + */ + mm_data->reg.sim_file_upd_ind_rec = TRUE; + + for (i = 0; i < file_upd->val_nr; i++) + { + if( file_upd->file_info[i].v_path_info EQ TRUE AND + file_upd->file_info[i].path_info.df_level1 EQ SIM_DF_GSM AND + file_upd->file_info[i].path_info.v_df_level2 EQ FALSE ) + { + switch (file_upd->file_info[i].datafield) + { + case SIM_ACC: /* Access control class */ + mm_data->reg.upd_sim_acc = SAT_READ_FILE; + break; + + case SIM_PLMNSEL: /* Preferred PLMN list */ + mm_data->reg.upd_sim_plmnsel = SAT_READ_FILE; + mm_data->reg.sim_plmnsel_len = NOT_PRESENT_16BIT; + /*Set indicator sim reading is in progress to true*/ + mm_data->reg.sim_read_in_progress = TRUE; + break; + + case SIM_HPLMN: /* Home PLMN search period */ + mm_data->reg.upd_sim_hplmn = SAT_READ_FILE; + break; + + case SIM_FPLMN: /* Forbidden PLMN list */ + mm_data->reg.upd_sim_fplmn = SAT_READ_FILE; + break; + +#ifdef REL99 + case SIM_UCPS_ACTEC: /* User controlled PLMN selector with access technology list */ + mm_data->reg.upd_sim_ucps_at = SAT_READ_FILE; + mm_data->reg.sim_ucps_at_len = NOT_PRESENT_16BIT; + /* + * If EFPLMNwAcT is changed, MM must have to re-read EFOPLMNwAcT to + * make acomplete list of pref_plmn. Actual length which came in + * SIM_MM_INSERT_IND can be used for EFOPLMNwAcT since file is unchanged. + */ + mm_data->reg.upd_sim_ocps_at = SAT_READ_FILE; + /*Set indicator sim reading is in progress to true*/ + mm_data->reg.sim_read_in_progress = TRUE; + break; + + case SIM_OCPS_ACTEC: /* Operator controlled PLMN selector with access technology list*/ + /*If only this file is modified MM need not to re-read EFPLMNwAcT*/ + mm_data->reg.upd_sim_ocps_at = SAT_READ_FILE; + mm_data->reg.sim_ocps_at_len = NOT_PRESENT_16BIT; + /*Set indicator sim reading is in progress to true*/ + mm_data->reg.sim_read_in_progress = TRUE; + break; +#endif + + case SIM_IMSI: + case SIM_LOCI: /* Does not happen this way, this is SIM_MM_INSERT_IND */ + /* FALLTHROUGH */ + case SIM_BCCH: + case SIM_KC: /* Guaranteed to not happen */ + TRACE_ERROR ("File change not handled"); + break; + + default: /* MM is not interested in this elementary file */ + break; + } + } + else if((file_upd->file_info[i].path_info.df_level1 EQ SIM_DF_CING) AND + (file_upd->file_info[i].path_info.v_df_level2 EQ TRUE) AND + (file_upd->file_info[i].path_info.df_level2 EQ SIM_DF2_CING) AND + (file_upd->file_info[i].datafield EQ SIM_CING_AHPLMN)) + { + mm_data->reg.upd_sim_act_hplmn = SAT_READ_FILE; + } + } + + PFREE (file_upd); + + /* Start reading SIM elementary files */ + if (reg_read_next_sim_file() EQ FALSE) + { + /* + * Nothing interesting for MM. Acknowledge completion of file update + */ + PALLOC (update_res, SIM_FILE_UPDATE_RES); /* T_SIM_FILE_UPDATE_RES */ + update_res->source = SRC_MM; + update_res->fu_rsc = SIM_FU_SUCCESS; + PSENDX (SIM, update_res); + mm_data->reg.sim_file_upd_ind_rec = FALSE; + + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_send_sim_sync_req | ++--------------------------------------------------------------------+ + + PURPOSE : Sends the primitive SIM_SYNC_REQ with cause. + +*/ + +GLOBAL void reg_send_sim_sync_req (void) +{ + GET_INSTANCE_DATA; + PALLOC (sync_req, SIM_SYNC_REQ); + sync_req->synccs = (U8)SYNC_MM_FINISHED_READING; + PSENDX (SIM, sync_req); + mm_data->reg.sim_sync_req_pending = FALSE; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_sim_read_cnf | ++--------------------------------------------------------------------+ + + PURPOSE : Process the primitive SIM_READ_CNF. + +*/ + +GLOBAL void reg_sim_read_cnf (T_SIM_READ_CNF *sim_read_cnf) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("reg_sim_read_cnf()"); + + switch (mm_data->sim_read_req_data_field) + { + case SIM_ACC: /* Access control class */ + assert ((sim_read_cnf->cause EQ SIM_NO_ERROR) AND + (sim_read_cnf->length >= 2)); + + mm_data->reg.upd_sim_acc = SAT_PEND_ACT; /* RR_ACTIVATE_REQ later */ + mm_data->reg.acc_class = sim_read_cnf->trans_data[0] * 256 + + sim_read_cnf->trans_data[1]; + break; + + case SIM_PLMNSEL: /* Preferred PLMN list, no further action */ + mm_data->reg.upd_sim_plmnsel = SAT_UNCHANGED; + + if (sim_read_cnf->cause EQ SIM_NO_ERROR) + { + reg_read_pref_plmn(sim_read_cnf->trans_data, sim_read_cnf->length); + +#ifdef REL99 + /* Set flage user/operator plmn selector with access tech. used to FALSE */ + mm_data->reg.sim_uocps_at_used = FALSE; +#endif + + } + else + { + + TRACE_EVENT_P2 ("SIM read cnf error file:%x, cause:%x", + SIM_PLMNSEL, sim_read_cnf->cause); + + } + if (mm_data->reg.sim_sync_req_pending EQ TRUE) + { + /* Allocate and send SIM_SYNC_REQ */ + reg_send_sim_sync_req(); + } + + break; + +#ifdef REL99 + case SIM_UCPS_ACTEC: + /*user controlled PLMN selector with access technology list, No Further action???*/ + mm_data->reg.upd_sim_ucps_at = SAT_UNCHANGED; + + if (sim_read_cnf->cause EQ SIM_NO_ERROR) + { + /* + * EF PLMNsel will not be used. PLMNsel only be used if EFs EFPLMNwAcT or EFOPLMNwAcT + * are not used. MM should not read EF SIM_PLMNSEL. + */ + mm_data->reg.upd_sim_plmnsel = SAT_UNCHANGED; + + if ( (mm_data->reg.sim_sync_req_pending == TRUE) && + (mm_data->reg.upd_sim_ocps_at != SAT_READ_FILE) ) /*EFOPLMNwAcT not read*/ + { + /*EFOPLMNwAcT already read. Allocate and send SIM_SYNC_REQ*/ + reg_send_sim_sync_req(); + } + + mm_data->reg.sim_uocps_at_used = TRUE; + reg_read_ucps_acctec(sim_read_cnf->trans_data, sim_read_cnf->length); + } + else + { + TRACE_EVENT_P2 ("SIM read cnf error file:%x, cause:%x", + SIM_UCPS_ACTEC, sim_read_cnf->cause); + + mm_data->reg.sim_ucps_at_len = 0; + if (mm_data->reg.upd_sim_ocps_at EQ SAT_UNCHANGED) + { + /* + * EF PLMNsel can be used if indicated because EF EFPLMNwAcT reading error and + * EFOPLMNwAcT is not indicated. + */ + mm_data->reg.sim_uocps_at_used = FALSE; + } + } + break; + case SIM_OCPS_ACTEC: + /* + * Read Operator controlled PLMN selector with access technology list. + * This can happens only after SIM insert indication indicates to read file from SIM. + */ + mm_data->reg.upd_sim_ocps_at = SAT_UNCHANGED; + if (sim_read_cnf->cause EQ SIM_NO_ERROR) + { + /* + * EF PLMNsel will not be used. PLMNsel only be used if EFs EFPLMNwAcT or EFOPLMNwAcT + * are not used. MM should not read EF SIM_PLMNSEL. + */ + mm_data->reg.upd_sim_plmnsel = SAT_UNCHANGED; + + if ( mm_data->reg.sim_sync_req_pending == TRUE ) + { + /*EFPLMNwAcT already read. Allocate and send SIM_SYNC_REQ*/ + reg_send_sim_sync_req(); + } + + mm_data->reg.sim_uocps_at_used = TRUE; + reg_read_ocps_acctec(sim_read_cnf->trans_data, sim_read_cnf->length); + } + else + { + /* + * EF PLMNsel can be used if indicated and if there was any error during reading of + * EF EFPLMNwAcT. + */ + TRACE_EVENT_P2 ("SIM read cnf error file:%x, cause:%x", + SIM_OCPS_ACTEC, sim_read_cnf->cause); + } + break; +#endif + + case SIM_HPLMN: /* Home PLMN search period */ + assert ((sim_read_cnf->cause EQ SIM_NO_ERROR) AND + (sim_read_cnf->length >= 1)); + + mm_data->reg.upd_sim_hplmn = SAT_PEND_ACT; /* RR_SYNC_REQ later */ + mm_data->reg.thplmn = sim_read_cnf->trans_data[0]; + if (mm_data->reg.thplmn > HPLMN_MAX_SEARCH_PERIOD) + { + /* 3GPP 22.011 subclause 3.2.2.5 requires to use the default value + * if the value delivered by the SIM exceeds the allowed limit. */ + mm_data->reg.thplmn = HPLMN_DEF_SEARCH_PERIOD; + } + break; + + case SIM_FPLMN: /* Forbidden PLMN list, no further action */ + { + T_forb_plmn forb_plmn; /* Maybe avoidable by unclean cast */ + + assert(sim_read_cnf->cause EQ SIM_NO_ERROR); + + /* Store new forbidden PLMN list, does this happen? */ + mm_data->reg.upd_sim_fplmn = SAT_UNCHANGED; + forb_plmn.c_forb = sim_read_cnf->length; + memcpy (forb_plmn.forb, + sim_read_cnf->trans_data, + sizeof (forb_plmn.forb)); + reg_read_forb_plmn (&forb_plmn); + } + break; + + case SIM_CING_AHPLMN: /* AHPLMN Value read, RR_SYNC_REQ later */ + { + U8 ahplmn[3]; + + assert(sim_read_cnf->cause EQ SIM_NO_ERROR); + + mm_data->reg.upd_sim_act_hplmn = SAT_PEND_ACT; + mm_data->reg.reg_plmn_equal_ahplmn = FALSE; + + /* If the current RPLMN is AHPLMN then set the flag to true */ + if ( mm_data->reg.acting_hplmn.v_plmn AND + reg_plmn_equal_rplmn(&mm_data->reg.acting_hplmn)) + { + mm_data->reg.reg_plmn_equal_ahplmn = TRUE; + } + + memcpy(ahplmn, + sim_read_cnf->trans_data, + sizeof(ahplmn)); + reg_read_acting_hplmn(ahplmn); + } + break; + + case SIM_IMSI: /* IMSI */ + case SIM_LOCI: /* Location information, not expected without IMSI */ + break; /* This will not happen this way */ + + case SIM_KC: + case SIM_BCCH: /* Guaranteed not to be changed by SAT */ + break; + + default: + break; + } /* switch */ + + mm_data->sim_read_req_data_field = NOT_PRESENT_16BIT; + + PFREE (sim_read_cnf); + + /* Read next changed elementary file */ + if (reg_read_next_sim_file() EQ FALSE) + { + /* All changed SIM files read */ + /* Acknowledge completion of file update */ + /* SIM_FILE_UPDATE_RES should be sent immediately after response + from SIM : Issue 23561*/ + if(mm_data->reg.sim_file_upd_ind_rec) + { + + PALLOC (update_res, SIM_FILE_UPDATE_RES); /* T_SIM_FILE_UPDATE_RES */ + update_res->source = SRC_MM; + update_res->fu_rsc = SIM_FU_SUCCESS; + PSENDX (SIM, update_res); + mm_data->reg.sim_file_upd_ind_rec = FALSE; + } + /* + * Set sim mm read in progress to False since MM has completed reading of + * EFs(PLMNsel/EF EFPLMNwAcT/EFOPLMNwAcT) indicated in primitive SIM_MM_INSERT_IND + * /SIM_MM_INFO_IND/SIM_FILE_UPDATE_IND. Also check if there was any rr_abort_ind + * was received and stored becuaseof SIM reading was in progress. + */ + if(mm_data->reg.sim_read_in_progress) + { + mm_data->reg.sim_read_in_progress = FALSE; + USE_STORED_ENTRIES(); + } + if (mm_data->reg.upd_sim_acc NEQ SAT_UNCHANGED) + { + /* + * MM has to send a RR_SYNC_REQ + * The actual changes of these fields are not tested by GSM 11.11 + */ + mm_data->reg.upd_sim_acc = SAT_UNCHANGED; + + /* Inform RR about changes by SAT */ + mm_build_rr_sync_req_cause (SYNCCS_ACCC); + } + + + if (mm_data->reg.upd_sim_hplmn NEQ SAT_UNCHANGED) + { + if (mm_data->first_attach_mem AND + mm_data->reg.thplmn NEQ 0) + { + /* do nothing : MM is in initial search period. So, the timer + should not be restarted. The new value is stored and after initial + search the timer should be restarted with this new value*/ + } + else + { + /* Start HPLMN search timer with new value */ + reg_stop_hplmn_tim (); + reg_check_hplmn_tim(mm_data->reg.thplmn); + } + }/*end of mm_data->reg.upd_sim_hplmn*/ + + + if (mm_data->reg.upd_sim_act_hplmn NEQ SAT_UNCHANGED ) + { + BOOL valid_ahplmn= FALSE; + valid_ahplmn = valid_acting_hplmn(&mm_data->reg.acting_hplmn); + mm_build_rr_sync_hplmn_req(); + if (valid_ahplmn) + { + /* Delete the AHPLMN entry from the Forbidden list, if present*/ + if ( mm_data->reg.acting_hplmn.v_plmn) + { + /* Remove from forbidden PLMN list if stored */ + TRACE_FUNCTION(" AHPLMN is being deleted from the Forbidden List"); + reg_plmn_bad_del (mm_data->reg.forb_plmn, + MAX_FORB_PLMN_ID, + &mm_data->reg.acting_hplmn); + } + + /*Inform ACI of the new AHPLMN value*/ + mm_mmgmm_ahplmn_ind(&mm_data->reg.acting_hplmn); + + /* Delete any Equivalent PLMN list */ + reg_clear_plmn_list (mm_data->reg.eqv_plmns.eqv_plmn_list, EPLMNLIST_SIZE); + + + /* If AHPLMN value read from SIM is same as the RPLMN then inform + * RR about it. No need of registering again. Set the flag + * to true so that hplmn will now be taken from this + */ + if (reg_plmn_equal_rplmn(&mm_data->reg.acting_hplmn)) + { + reg_stop_hplmn_tim (); + } + else + { + mm_data->plmn_scan_mm = TRUE; + /* Start with AHPLMN registration */ + mm_func_mmgmm_net_req(); + } + } + else + { + T_plmn hplmn; + + /*Inform ACI of the new AHPLMN value*/ + mm_mmgmm_ahplmn_ind(&mm_data->reg.acting_hplmn); + + /* Since mm_data->reg.acting_hplmn.v_plmn is FALSE it will take HPLMN from IMSI */ + reg_extract_hplmn(&hplmn); + + if (reg_plmn_equal_rplmn(&hplmn)) + { + /* Do Nothing. MS is already registered to True-HPLMN */ + } + else + { + /* If AHPLMN is FFFFFF OR we are on already on an AHPLMN MM should + * immediately start a network search for HPLMN + */ + if (mm_data->reg.acting_hplmn_invalid OR + mm_data->reg.reg_plmn_equal_ahplmn) + { + mm_data->plmn_scan_mm = TRUE; + mm_func_mmgmm_net_req(); + } + else + { + /*Do Nothing. Since MS is registered to any other PLMN HPPLMN + Timer will be running. Network scan will start after the + Timer expires + */ + } + }/*reg_plmn_equal_rplmn*/ + }/*valid_acting_hplmn*/ + check_if_cingular_sim(); /*for cingular only 31179*/ + }/*end of mm_data->reg.upd_sim_act_hplmn*/ + }/*end of reg_read_next_sim_file*/ +}/*end of reg_sim_read_cnf*/ + + +#endif +