FreeCalypso > hg > fc-magnetite
diff src/g23m-gprs/gmm/gmm_kernp.c @ 183:219afcfc6250
src/g23m-gprs: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 13 Oct 2016 04:24:13 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-gprs/gmm/gmm_kernp.c Thu Oct 13 04:24:13 2016 +0000 @@ -0,0 +1,4260 @@ +/* ++----------------------------------------------------------------------------- +| Project : GPRS (8441) +| Modul : gmm_kernp.c ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : This modul is part of the entity GMM and implements all +| functions to handles the incoming primitives as described in +| the SDL-documentation (KERN-statemachine) ++----------------------------------------------------------------------------- +*/ + + + +#ifndef GMM_KERNP_C +#define GMM_KERNP_C +#endif + +#define ENTITY_GMM + +/*==== INCLUDES =============================================================*/ + +#include "typedefs.h" /* to get Condat data types */ +#include "vsi.h" /* to get a lot of macros */ +#include "macdef.h" +#include "gprs.h" +#include "gsm.h" /* to get a lot of macros */ +#include "ccdapi.h" /* to get CCD API */ +#include "cnf_gmm.h" /* to get cnf-definitions */ +#include "mon_gmm.h" /* to get mon-definitions */ +#include "prim.h" /* to get the definitions of used SAP and directions */ +#include "gmm.h" /* to get the global entity definitions */ + +#include "gmm_f.h" /* to ger the gobal functions */ +#include "gmm_kernl.h" /* to ger the local functions */ +#include "gmm_kernf.h" /* to ger the local functions */ +#include "gmm_rdys.h" /* to get some signals */ +#include <string.h> /* to get memcpy */ +#include "gmm_txs.h" /* to get some signals */ +#include "gmm_syncs.h" +#include "gmm_em.h" /* To get Engineering Mode functions */ + +/*==== CONST ================================================================*/ + +/*==== LOCAL VARS ===========================================================*/ + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +/*==== PUBLIC FUNCTIONS =====================================================*/ + +/* ++------------------------------------------------------------------------------ +| Function : kern_t3302 ++------------------------------------------------------------------------------ +| Description : Handles expiry of timer T3302. This function is called from +| pei_primitive(). +| Timeout for Attach or RAU failure +| Parameters : none +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_t3302(void) +{ + GMM_TRACE_FUNCTION( "kern_t3302" ); + TRACE_0_INFO("TIMEOUT T3302"); + sig_kern_rdy_stop_t3302_req(); + /* + * reset attach attempt counter + * <R.GMM.ATTACH.M.010> + */ + /* + * reset rau attempt counter + * <R.GMM.ATTACH.M.010> + */ + + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_DEREG_SUSPENDING: + case KERN_GMM_DEREG_SUSPENDED: + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau=FALSE; + break; + case KERN_GMM_REG_SUSPENDING: + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau=FALSE; + SET_STATE(GU,GU_UPDATE_NEEDED); + break; + case KERN_GMM_REG_RESUMING: + case KERN_GMM_REG_SUSPENDED: + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau=FALSE; + SET_STATE(GU,GU_UPDATE_NEEDED); + break; + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + kern_attach_reset(); + kern_attach (); + break; + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + kern_attach_reset(); + + if (PERIODIC_RAU == gmm_data->kern.attach_cap.update_proc_type) + { + /* 44.2.3.3.2 */ + kern_periodic_rau(); + } + else + { + kern_rau_limited(); + } + + break; + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + /* + * GPRS is still attached (normal service) + * so we need to resume LLC again + */ + kern_attach_reset(); + kern_rau(); + break; + default: + TRACE_ERROR( "kern_t3302 unexpected" ); + break; + } + GMM_RETURN; + +} /* kern_t3302 */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_t3310 ++------------------------------------------------------------------------------ +| Description : Handles expiry of timer T3310. This function is called from +| pei_primitive(). +| Timeout for ATTACH +| Parameters : none +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_t3310 (void) +{ + GMM_TRACE_FUNCTION( "kern_t3310" ); + TRACE_0_INFO("TIMEOUT T3310"); + + gmm_data->kern.attach_cap.t3310_value=0; + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_REG_INITIATED: + /************************************************************************ + * MSC: 3.8 Attach + * + * MSC: 3.8.1 Normal Attach + * MSC: 3.8.1.4 Abnormal cases + * MSC: 3.8.1.4.3 c) T3310 time-out + ************************************************************************/ + if ( gmm_data->kern.ct3310 < MAX_CT3310 ) + { + /* + * ATTACH + * <R.GMM.AGABNORM.M.007> + */ + kern_gmmreg_detach ( GMMREG_DT_GPRS, + GMMCS_NET_FAIL, /* TCS 2.1 */ + GMMREG_SEARCH_RUNNING, + GMMCS_NET_FAIL); + + kern_attach(); + } + else + { + /* + * AAC + *<R.GMM.AGABNORM.M.008> + */ + kern_aac(GMMCS_NO_SERVICE); /* TCS 2.1 */ + } + + break; + case KERN_GMM_RAU_INITIATED: + /************************************************************************ + * MSC: 3.10 RAU + * + * MSC: 3.10.1 Normal and periodic RAU initiation + * MSC: 3.10.1.4 Abnormal cases + * MSC: 3.10.1.4.3 c) T3310 time-out + * + ************************************************************************/ + /* + * I reused the timer T3310 instead of T3330 + */ + if ( gmm_data->kern.ct3310 < MAX_CT3310 ) + { + if (PERIODIC_RAU == gmm_data->kern.attach_cap.update_proc_type) + { + /* 44.2.3.3.2 */ + kern_periodic_rau(); + } + else + { + kern_rau_limited(); + } + } + else + { + /* + * AAC + */ + kern_aac(GMMCS_NO_SERVICE); /* TCS 2.1 */ + } + break; + /* START PATCH UBUOB ISSUE 8274 */ + case KERN_GMM_REG_RESUMING: + case KERN_GMM_REG_SUSPENDING: + case KERN_GMM_REG_SUSPENDED: + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau = FALSE; + SET_STATE(GU,GU_UPDATE_NEEDED); + break; + /* END PATCH UBUOB ISSUE 8274 */ + case KERN_GMM_REG_LIMITED_SERVICE: + TRACE_EVENT("T3310 ignored in limited mode"); + break; + default: + TRACE_ERROR( "kern_t3310 unexpected" ); + break; + } + GMM_RETURN; +} /* kern_t3310 */ +/* ++------------------------------------------------------------------------------ +| Function : kern_t3311 ++------------------------------------------------------------------------------ +| Description : Handles expiry of timer T3310. This function is called from +| pei_primitive(). +| Timeout for ATTACH or RAU Reject +| Parameters : none +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_t3311 (void) +{ + GMM_TRACE_FUNCTION( "kern_t3311" ); + TRACE_0_INFO("TIMEOUT T3311"); + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + kern_attach (); + break; + case KERN_GMM_REG_NORMAL_SERVICE: + /* + * <R.GMM.RNABNORM.M.022> + */ + kern_periodic_rau(); + break; + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + kern_llgmm_suspend(LLGMM_RAU); + /*FALLTHROUGH*/ + //lint -fallthrough + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + kern_rau_limited (); + break; + /* START PATCH UBUOB ISSUE 8893 */ + case KERN_GMM_DEREG_SUSPENDING: + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_DEREG_RESUMING: + /* END PATCH UBUOB ISSUE 8893 */ + case KERN_GMM_REG_RESUMING: + /* START PATCH UBUOB ISSUE 8273 */ + case KERN_GMM_REG_SUSPENDING: + case KERN_GMM_REG_SUSPENDED: + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau = FALSE; + SET_STATE(GU,GU_UPDATE_NEEDED); + break; + /* END PATCH UBUOB ISSUE 8273 */ + default: + TRACE_ERROR( "kern_t3311 unexpected" ); + break; + } + + GMM_RETURN; +} /* kern_t3311 */ +/* ++------------------------------------------------------------------------------ +| Function : kern_t3312 ++------------------------------------------------------------------------------ +| Description : Handles expiry of timer T3312. This function is called from +| pei_primitive(). + +| Periodic RAU timer +| Parameters : none +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_t3312 (void) +{ + GMM_TRACE_FUNCTION( "kern_t3312" ); + TRACE_0_INFO("TIMEOUT T3312"); + switch( GET_STATE( KERN ) ) + { + + case KERN_GMM_REG_NORMAL_SERVICE: + if (GMM_GRR_STATE_CR==gmm_data->kern.attach_cap.grr_state) + { + gmm_data->kern.timeout_t3312 = TRUE; + SET_STATE(GU,GU_UPDATE_NEEDED); + } + else + { + kern_periodic_rau(); + } + break; + case KERN_GMM_REG_NO_CELL_AVAILABLE: + /* + * 24.008 ch 4.7.2.2. at the end: + * + * If the MS is both IMSI attached for GPRS and non-GPRS services in a network that + * operates in network operation mode I, and if the MS has camped on a cell that does + * not support GPRS, and timer T3312 expires, then the MS shall start an MM location + * updating procedure. In addition, the MS shall perform a combined routing area update + * procedure indicating "combined RA/LA updating with IMSI attach" when the MS enters + * a cell that supports GPRS and indicates that the network is in operation mode I. + */ + gmm_data->kern.timeout_t3312 = TRUE; + SET_STATE(GU,GU_UPDATE_NEEDED); + + if (GMM_MM_DEREG != GET_STATE(MM) + && GMMRR_LA_INVALID!=gmm_data->kern.sig_cell_info.env.rai.lac) + { + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDING); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDING); +#endif + kern_llgmm_suspend(LLGMM_CALL); /* in no cell availble LLC is alread susended */ + kern_gmmrr_suspend(GMMRR_NOT_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_LAU); + } + break; + + + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_REG_IMSI_DETACH_INITIATED: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_REG_RESUMING: + case KERN_GMM_REG_SUSPENDING: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + case KERN_GMM_REG_SUSPENDED: + /* no break; */ + /* + * <R.GMM.RAUTIMER.M.009> + */ + gmm_data->kern.timeout_t3312 = TRUE; + SET_STATE(GU,GU_UPDATE_NEEDED); + break; + default: + break; + } + + GMM_RETURN; +} /* kern_t3312 */ +/* ++------------------------------------------------------------------------------ +| Function : kern_t3321 ++------------------------------------------------------------------------------ +| Description : Handles expiry of timer T3321. This function is called from +| pei_primitive(). +| Timeout for DETACH +| +| MSC: 3.9 GPRS detach procedure +| +| MCS: 3.9.3 Abnormal cases +| MSC: 3.9.3.1 a) Timeout of timer T3321 +| +| Parameters : none +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_t3321 (void) +{ + +#ifdef REL99 + T_gmobile_identity gmobile_identity; /* TCS 4.0 */ +#endif + + GMM_TRACE_FUNCTION( "kern_t3321" ); + TRACE_0_INFO("TIMEOUT T3321"); + /* + * MSC: 3.9 GPRS detach procedure + * + * MCS: 3.9.3 Abnormal cases + * MSC: 3.9.3.1 a) Timeout of timer T3321 + */ + if ( ++gmm_data->kern.ct3321 < 5 ) + { + MCAST (u_detach_request, U_DETACH_REQUEST); + + TRACE_EVENT (" START T3321" ); + sig_kern_rdy_start_timer_req ( kern_T3321, gmm_data->kern.t3321_val ); + + u_detach_request->u_detach_type.u_type_of_detach + = gmm_data->kern.detach_cap.detach_type, + u_detach_request->u_detach_type.power_off = PO_NORMAL_DETACH; + + +#ifdef REL99 + /* Detach request sent to a Release 99 network has two addional + * parameters. PTMSI and PTMSI signature + */ + switch (gmm_data->kern.sig_cell_info.sgsnr_flag)/*!gmm_data->release99 =>old code*/ /* TCS 4.0 */ + { + default: + case PS_SGSN_UNKNOWN: + case PS_SGSN_98_OLDER: + u_detach_request->v_gmobile_identity = FALSE; /* TCS 4.0 */ + u_detach_request->v_p_tmsi_signature_2 = FALSE; /* TCS 4.0 */ + break; + case PS_SGSN_99_ONWARDS: + /* + * PTMSI + */ + kern_ulong2mobile_identity( gmm_data->ptmsi.current, &gmobile_identity ); /* TCS 4.0 */ + u_detach_request->v_gmobile_identity = TRUE; /* TCS 4.0 */ + u_detach_request->gmobile_identity = gmobile_identity; /* TCS 4.0 */ + + /* + * PTMSI Signature + */ + if(gmm_data->ptmsi_signature.available) /* TCS 4.0 */ + { /* TCS 4.0 */ + u_detach_request->v_p_tmsi_signature_2 =TRUE; /* TCS 4.0 */ + u_detach_request->p_tmsi_signature_2.p_tmsi_signature_value /* TCS 4.0 */ + = gmm_data->ptmsi_signature.value; /* TCS 4.0 */ + } /* TCS 4.0 */ + else /* TCS 4.0 */ + { /* TCS 4.0 */ + u_detach_request->v_p_tmsi_signature_2=FALSE; /* TCS 4.0 */ + } /* TCS 4.0 */ + break; + } +#endif + + + switch ( gmm_data->kern.detach_cap.detach_type ) + { + case GMMREG_DT_GPRS: + u_detach_request->u_detach_type.u_type_of_detach + = DT_GPRS; + break; + case GMMREG_DT_IMSI: + u_detach_request->u_detach_type.u_type_of_detach + = DT_IMSI; + break; + case GMMREG_DT_COMB: + u_detach_request->u_detach_type.u_type_of_detach + = DT_COMB; + break; + case GMMREG_DT_SIM_REMOVED: + if ( GMM_MM_DEREG != GET_STATE(MM) ) + { + u_detach_request->u_detach_type.u_type_of_detach + = DT_COMB; + } + else + { + u_detach_request->u_detach_type.u_type_of_detach + = DT_GPRS; + } + break; + default: + TRACE_ERROR ("unexpexted GMMREG_DT_TYPE"); + break; + } + kern_mm_detach_started (); + sig_kern_tx_data_req ( CURRENT_TLLI, U_DETACH_REQUEST); + } + else + { + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_DEREG_INITIATED: + kern_local_detach( GMMCS_INT_NOT_PRESENT, FALSE, GMM_LOCAL_DETACH_PROC_ENTER_DEREG); /* TCS 2.1 */ + break; + case KERN_GMM_REG_IMSI_DETACH_INITIATED: + /* + * <R.GMM.DMABNORM.M.020> + */ + kern_local_detach( GMMCS_INT_NOT_PRESENT, FALSE, GMM_LOCAL_DETACH_PROC_ENTER_REG_NORMAL); /* TCS 2.1 */ + break; + default: + TRACE_ERROR( "kern_t3321 unexpected" ); + break; + } + } + GMM_RETURN; +} /* kern_t3321 */ +/* ++------------------------------------------------------------------------------ +| Function : kern_tpower_off ++------------------------------------------------------------------------------ +| Description : Handles expiry of timer Tpower_off. This function is called from +| pei_primitive(). +| Timeout for power_off after sending DETACH message +| Parameters : none +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_tpower_off (void) +{ + GMM_TRACE_FUNCTION( "kern_tpower_off" ); + TRACE_0_INFO("TIMEOUT TPOWER_OFF"); + kern_local_detach( GMMCS_POWER_OFF, FALSE, /* TCS 2.1 */ + GMMREG_DT_SOFT_OFF==gmm_data->kern.detach_cap.detach_type? + GMM_LOCAL_DETACH_PROC_SOFT_OFF: + GMM_LOCAL_DETACH_PROC_POWER_OFF); + + GMM_RETURN; + +} /* kern_tpower_off */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_tlocal_detach ++------------------------------------------------------------------------------ +| Description : Handles expiry of timer Tlocal_detach. This function is called from +| pei_primitive(). +| function local_detach is called to locally detach the MS. +| GRR and LLC can not unassigned immediately. So GMM waits untill +| the tlocal_detach timer has been expired or either CGRLC_TRIGGER_IND +| has been received or GMMRR_SUSPEND_CNF has been received. +| Parameters : none +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_tlocal_detach (void) +{ + GMM_TRACE_FUNCTION( "kern_tlocal_detach" ); + + + switch( GET_STATE( KERN ) ) + { + default: + TRACE_ERROR("tlocal_detach not in state DEREG_SUSPENDING"); + /* NO break; */ + case KERN_GMM_DEREG_SUSPENDING: + kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_NORMAL_RELEASE, + GMM_SUSP_UNKNOWN); + + break; + } + + GMM_RETURN ; +} /* kern_tlocal_detach */ + + + + +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmreg_net_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMREG_NET_REQ +| +| MSC: 3.20 MM Interface +| MSC: 3.20.2 Network selection +| +| Parameters : *gmmreg_net_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmreg_net_req ( T_GMMREG_NET_REQ *gmmreg_net_req ) +{ + GMM_TRACE_FUNCTION( "kern_gmmreg_net_req" ); + + PFREE (gmmreg_net_req); + kern_mm_net_req(); + GMM_RETURN; +} /* kern_gmmreg_net_req() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmreg_plmn_res ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMREG_PLMN_RES +| +| MSC: 3.20 MM Interface +| MSC: 3.20.2 Network selection +| +| Parameters : *gmmreg_plmn_res - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmreg_plmn_res ( T_GMMREG_PLMN_RES *gmmreg_plmn_res ) +{ + GMM_TRACE_FUNCTION( "kern_gmmreg_plmn_res" ); + + gmm_data->kern.attach_cap.network_selection_mode=MODE_MAN; + kern_remove_plmn_from_forbidden_list(gmmreg_plmn_res->plmn); + + /* START PATCH UBUOB ISSUE 8276 */ + /* T3302 should not be stopped here, because this is dangerous if the */ + /* user selection does not lead to a different PLMN */ + /*vsi_t_stop ( GMM_handle, kern_T3302);*/ + /*sig_kern_rdy_start_t3302_req();*/ + /* END PATCH UBUOB ISSUE 8276 */ + + /* When we receive manual mode network selection stop TSYNC timer */ + vsi_t_stop ( GMM_handle, sync_TSYNC); + + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau = FALSE; + /* + * attach_cap.gmmreg sets the caller of the attach procedure to MMI + */ + gmm_data->kern.attach_cap.gmmreg = TRUE; + /* + * if the moble has been rejected with cause #11,#12, or #13 it has to igored + * when user wanted the moile explicitly to try to attach + * TC 44.2.1.1.4.3.2 + */ + gmm_data->kern.detach_cap.error_cause=GMMCS_INT_NOT_PRESENT; /* TCS 2.1 */ + + /* Setting mm_status to FULL Service immediately on receiving PLMN Response creates a false display + * on MMI if selecting forbidden PLMN second time in a row. However, it is necessary in case of Normal PLMN selection + * for an early indication to ACI. Hence setting mm_status to Full Service only if the selected PLMN was not rejected by + * the N/W in the same power cycle. + */ + if((memcmp(gmm_data->kern.attach_cap.list_of_forbidden_plmns_for_gprs_service[0].mcc,gmmreg_plmn_res->plmn.mcc, SIZE_MCC) NEQ 0) AND + (memcmp(gmm_data->kern.attach_cap.list_of_forbidden_plmns_for_gprs_service[0].mnc,gmmreg_plmn_res->plmn.mnc, SIZE_MNC)NEQ 0)) + { + gmm_data->kern.sig_cell_info.mm_status = MMGMM_FULL_SERVICE; + sig_kern_sync_set_mm_state(MMGMM_FULL_SERVICE); + } + +#ifndef NTRACE + /* + * My assumption is, that I have to know the class if plmn_res comes as power + * on primitive with AT+COPS=1,2,"001001". There are no possabilities to + * change the classes. a class change is handeled with attach_req + */ + if(gmm_data->kern.attach_cap.mobile_class!=gmmreg_plmn_res->mobile_class) + { + TRACE_ERROR("class change not expected: NO DETACH_REQ will be send!"); + } +#endif + gmm_data->kern.attach_cap.plmn_requested = gmmreg_plmn_res->plmn; + gmm_data->kern.attach_cap.mobile_class = gmmreg_plmn_res->mobile_class; + gmm_data->kern.attach_cap.attach_type = gmmreg_plmn_res->attach_type; +#ifndef NTRACE + switch ( gmm_data->kern.attach_cap.mobile_class ) + { + case GMMREG_CLASS_CC: + TRACE_0_PARA ("MS class CC"); + break; + case GMMREG_CLASS_CG: + TRACE_0_PARA ("MS class CG"); + break; + case GMMREG_CLASS_B: + TRACE_0_PARA ("MS class B"); + break; + case GMMREG_CLASS_BG: + TRACE_0_PARA ("MS class BG"); + break; + case GMMREG_CLASS_BC: + TRACE_0_PARA ("MS class BC"); + break; + case GMMREG_CLASS_A: + TRACE_0_PARA ("MS class A"); + break; + default: + TRACE_ERROR ("unknown mobile class"); + break; + } + switch (gmm_data->kern.attach_cap.attach_type) + { + case GMMREG_AT_IMSI: + TRACE_EVENT ("----- GSM only attach -----"); + break; + case GMMREG_AT_GPRS: + TRACE_EVENT ("----- GPRS attach -----"); + break; + case GMMREG_AT_COMB: + TRACE_EVENT ("----- GSM and GPRS attach -----"); + break; + default: + TRACE_ERROR ("unknown attach type"); + break; + } + +#endif + { + PALLOC ( mmgmm_plmn_res, MMGMM_PLMN_RES); + mmgmm_plmn_res->plmn = gmmreg_plmn_res->plmn; + mmgmm_plmn_res->reg_type = REG_CELL_SEARCH_ONLY; + PFREE (gmmreg_plmn_res); + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ: + case KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ: + mmgmm_plmn_res->reg_type = REG_GPRS_INACTIVE; + break; + case KERN_GMM_NULL_NO_IMSI: + if (GMMREG_CLASS_CC==gmm_data->kern.attach_cap.mobile_class + || GMMREG_AT_IMSI== gmm_data->kern.attach_cap.attach_type) + { + /* NO state change */ + } + else + { + SET_STATE ( KERN, KERN_GMM_DEREG_NO_IMSI); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_NO_IMSI); +#endif + } + mmgmm_plmn_res->reg_type = REG_GPRS_INACTIVE; + + break; + + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_REG_RESUMING: + case KERN_GMM_DEREG_NO_IMSI: + break; + /* + * GMM-DEREGISTERED + */ + case KERN_GMM_DEREG_SUSPENDING: + /* + * not reachable beause of save in pei + */ + case KERN_GMM_DEREG_SUSPENDED: + kern_resume_grr_der(); + /* NO break;*/ + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_DEREG_LIMITED_SERVICE: + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + if (GMMREG_CLASS_CC==gmm_data->kern.attach_cap.mobile_class + || GMMREG_AT_IMSI== gmm_data->kern.attach_cap.attach_type) + { + SET_STATE ( KERN, KERN_GMM_NULL_PLMN_SEARCH); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_PLMN_SEARCH); +#endif + mmgmm_plmn_res->reg_type = REG_GPRS_INACTIVE; + } + else + { + SET_STATE ( KERN, KERN_GMM_DEREG_PLMN_SEARCH); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_PLMN_SEARCH); +#endif + } + + break; + + case KERN_GMM_NULL_PLMN_SEARCH: + case KERN_GMM_NULL_IMSI: + + if (GMMREG_CLASS_CC==gmm_data->kern.attach_cap.mobile_class + || GMMREG_AT_IMSI== gmm_data->kern.attach_cap.attach_type) + { + SET_STATE ( KERN, KERN_GMM_NULL_PLMN_SEARCH); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_PLMN_SEARCH); +#endif + mmgmm_plmn_res->reg_type = REG_GPRS_INACTIVE; + } + else + { + SET_STATE ( KERN, KERN_GMM_DEREG_PLMN_SEARCH); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_PLMN_SEARCH); +#endif + kern_gmmrr_enable(); + } + + break; + + case KERN_GMM_REG_NORMAL_SERVICE: + + case KERN_GMM_REG_NO_CELL_AVAILABLE: + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_RAU_INITIATED: + case KERN_GMM_REG_INITIATED: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + break; + case KERN_GMM_REG_SUSPENDING: + /* + * not reachablebeause of save in pei + */ + case KERN_GMM_REG_SUSPENDED: + /* + * Attach requests in suspended mode will be handled after resumption + * by triggering form GRR with GMMRR_CELL_IND + */ + + /* + * The user is not allowed to change the mobile class or establish a + * voice call the same time manuall network search is started. it would + * not be nice + */ + kern_resume_grr_reg(); + + TRACE_ERROR("I hoped, that this never is happened, ..."); + break; + default: + TRACE_ERROR( "GMMREG_PLMN_RES unexpected" ); + break; + + } + mmgmm_plmn_res->mobile_class=gmm_data->kern.attach_cap.mobile_class; + PSEND ( hCommMM, mmgmm_plmn_res ); + } + GMM_RETURN; +} /* kern_gmmreg_plmn_res() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmreg_plmn_mode_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMREG_PLMN_MODE_REQ +| +| MSC: 3.20 MM Interface +| MSC: 3.20.1 Change of PLMN Mode +| +| Parameters : *gmmreg_plmn_mode_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmreg_plmn_mode_req ( T_GMMREG_PLMN_MODE_REQ *gmmreg_plmn_mode_req ) +{ + GMM_TRACE_FUNCTION( "kern_gmmreg_plmn_mode_req" ); + { + PPASS ( gmmreg_plmn_mode_req, mmgmm_plmn_mode_req, MMGMM_PLMN_MODE_REQ ); + /* + * PATCH UBUOB 11.3.02: if we change from MANUAL to AUTOMATC or vice versa, + * then we need to clear the limited_service flag + * Problem was: Bouyg SIM, manual registration on SFR upon return to + * auto mode, first GPRS ATTACH + + if (gmm_data->kern.attach_cap.network_selection_mode + != gmmreg_plmn_mode_req->net_selection_mode) + { + gmm_data->kern.sig_cell_info.mm_status = MMGMM_FULL_SERVICE; + sig_kern_sync_set_mm_state(MMGMM_FULL_SERVICE); + } + */ + /* + * PLMN mode set to manual mode with PLMN_RES only + gmm_data->kern.attach_cap.network_selection_mode = + gmmreg_plmn_mode_req->net_selection_mode; + */ + if (GMMREG_NET_SEL_MODE_AUTO == gmmreg_plmn_mode_req->net_selection_mode) + { + gmm_data->kern.attach_cap.network_selection_mode = + gmmreg_plmn_mode_req->net_selection_mode; + } + else + { + TRACE_0_INFO ("manual mode ignored. will be set with PLMN_RES"); + } + + PSEND ( hCommMM, mmgmm_plmn_mode_req ); + } + GMM_RETURN; +} /* kern_gmmreg_plmn_mode_req () */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmreg_config_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMREG_CONFIG_REQ +| +| Parameters : *gmmreg_config_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmreg_config_req ( T_GMMREG_CONFIG_REQ *gmmreg_config_req ) +{ + GMM_TRACE_FUNCTION( "kern_gmmreg_config_req" ); + gmm_data->config.cipher_on + = gmmreg_config_req->cipher_on; + PFREE (gmmreg_config_req); + GMM_RETURN; +} /* kern_gmmreg_plmn_mode_req () */ +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmreg_detach_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMREG_DETACH_REQ +| +| Parameters : *gmmreg_detach_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmreg_detach_req ( T_GMMREG_DETACH_REQ *gmmreg_detach_req ) +{ + GMM_TRACE_FUNCTION( "kern_gmmreg_detach_req" ); + + /* + * RAU may interrupt detach procedure, so we have to store the detach type + */ + gmm_data->kern.detach_cap.detach_type=gmmreg_detach_req->detach_type; + gmm_data->kern.detach_cap.gmmreg=TRUE; + + switch (gmmreg_detach_req->detach_type) + { + case GMMREG_DT_GPRS: + switch(gmm_data->kern.attach_cap.attach_type) + { + case GMMREG_AT_GPRS: + case GMMREG_AT_NOT_KNOWN: + gmm_data->kern.attach_cap.attach_type=GMMREG_AT_NOT_KNOWN; + break; + default: + case GMMREG_AT_IMSI: + case GMMREG_AT_COMB: + gmm_data->kern.attach_cap.attach_type=GMMREG_AT_IMSI; + break; + } + TRACE_EVENT ("Para: GPRS detach"); + break; + case GMMREG_DT_IMSI: + gmm_data->kern.attach_cap.attach_type= + (GMMREG_CLASS_CC == gmm_data->kern.attach_cap.mobile_class? + GMMREG_AT_NOT_KNOWN: + GMMREG_AT_GPRS); + TRACE_EVENT ("Para: IMSI detach"); + break; + case GMMREG_DT_POWER_OFF: + /* + * TMSI reset to remove TMSI in GRR when gmmrr_assign_req will + * be sent + */ + gmm_data->tmsi = GMMRR_TMSI_INVALID; + gmm_data->kern.attach_cap.attach_type=GMMREG_AT_NOT_KNOWN; + gmm_data->kern.attach_cap.network_selection_mode=MODE_AUTO; + TRACE_EVENT ("Para: Power OFF"); + break; + case GMMREG_DT_SOFT_OFF: + /* + * TMSI reset to remove TMSI in GRR when gmmrr_assign_req will + * be sent + */ + gmm_data->tmsi = GMMRR_TMSI_INVALID; + gmm_data->kern.attach_cap.attach_type=GMMREG_AT_NOT_KNOWN; + TRACE_EVENT ("Para: Soft OFF"); + break; + case GMMREG_DT_COMB: + gmm_data->kern.attach_cap.service_mode=SERVICE_MODE_LIMITED; + gmm_data->kern.attach_cap.attach_type=GMMREG_AT_NOT_KNOWN; + TRACE_EVENT ("Para: GMMREG_DT_COMB"); + break; + case GMMREG_DT_SIM_REMOVED: + gmm_data->kern.attach_cap.attach_type=GMMREG_AT_NOT_KNOWN; + TRACE_EVENT ("Para: GMMREG_DT_SIM_REMOVED"); + break; + case GMMREG_DT_DISABLE_GPRS: + TRACE_EVENT ("Para: GMMREG_DT_DISABLE_GPRS"); + break; + case GMMREG_DT_LIMITED_SERVICE: + gmm_data->kern.attach_cap.service_mode=SERVICE_MODE_LIMITED; + TRACE_EVENT ("Para: GMMREG_DT_LIMITED_SERVICE"); + break; + default: + gmm_data->kern.attach_cap.attach_type= + (GMMREG_CLASS_CG == gmm_data->kern.attach_cap.mobile_class? + GMMREG_AT_NOT_KNOWN: + GMMREG_AT_IMSI); + vsi_o_ttrace(VSI_CALLER TC_ERROR,"Error: Unknown detach_type = %x", gmmreg_detach_req->detach_type); + break; + + + } + + gmm_data->kern.detach_cap.detach_type = gmmreg_detach_req->detach_type; + + gmm_data->kern.detach_cap.gmmreg = TRUE; + gmm_data->kern.attach_cap.gmmreg = FALSE; +#ifndef GMM_TCS4 + gmm_data->kern.attach_cap.gmmsm = FALSE; +#endif + + PFREE ( gmmreg_detach_req ); + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_REG_NO_CELL_AVAILABLE: + case KERN_GMM_REG_TEST_MODE: + case KERN_GMM_REG_TEST_MODE_NO_IMSI: + switch ( gmm_data->kern.detach_cap.detach_type ) + { + case GMMREG_DT_IMSI: + case GMMREG_DT_COMB: + case GMMREG_DT_SIM_REMOVED: + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDED); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDED); +#endif + kern_mm_imsi_detach(); + break; + case GMMREG_DT_DISABLE_GPRS: + kern_local_detach( GMMCS_INT_NOT_PRESENT, FALSE, + GMM_LOCAL_DETACH_PROC_ENTER_NULL_IMSI); /* TCS 2.1 */ + break; + case GMMREG_DT_GPRS: + kern_local_detach( GMMCS_INT_NOT_PRESENT, FALSE, + GMM_LOCAL_DETACH_PROC_ENTER_NULL_IMSI); /* TCS 2.1 */ + break; + case GMMREG_DT_POWER_OFF: + kern_local_detach( GMMCS_POWER_OFF, FALSE, /* TCS 2.1 */ + GMM_LOCAL_DETACH_PROC_POWER_OFF); + break; + case GMMREG_DT_SOFT_OFF: + kern_local_detach( GMMCS_POWER_OFF, FALSE, /* TCS 2.1 */ + GMM_LOCAL_DETACH_PROC_SOFT_OFF); + + break; + default: + TRACE_ERROR ("Unexpected detach type in primitive GMMREG_DETACH_REQ"); + break; + } + break; + case KERN_GMM_REG_INITIATED: + /* + * This cause is abnormal, because the normal and not the local detach + * procedure is started on power off + * + * MSC: 3.8.1.4.7 g) Power off + * <R.GMM.AGABNORM.M.015>, + * <R.GMM.AGABNORM.M.031> + */ + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + kern_gmmrr_attach_finished(); + /* NO break;*/ + + case KERN_GMM_REG_NORMAL_SERVICE: + switch ( gmm_data->kern.detach_cap.detach_type ) + { + case GMMREG_DT_IMSI: + case GMMREG_DT_COMB: + case GMMREG_DT_SIM_REMOVED: + switch (gmm_data->kern.sig_cell_info.net_mode) + { + case GMMRR_NET_MODE_I: + kern_detach( ); + break; + case GMMRR_NET_MODE_II: + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDING); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDING); +#endif + kern_llgmm_suspend(LLGMM_CALL); + kern_gmmrr_suspend(GMMRR_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_IMSI_DETACH); + break; + case GMMRR_NET_MODE_III: + kern_detach( ); + break; + default: + TRACE_ERROR ("unknown net mode"); + break; + } + break; + case GMMREG_DT_DISABLE_GPRS: + case GMMREG_DT_GPRS: + case GMMREG_DT_POWER_OFF: + case GMMREG_DT_SOFT_OFF: + kern_detach( ); + break; + + default: + TRACE_ERROR ("Unexpected detach type in primitive GMMREG_DETACH_REQ"); + break; + } + break; + + case KERN_GMM_REG_IMSI_DETACH_INITIATED: + switch ( gmm_data->kern.detach_cap.detach_type ) + { + case GMMREG_DT_DISABLE_GPRS: + gmm_data->kern.attach_cap.mobile_class = GMMREG_CLASS_CC; + /* NO break */ + default: + kern_detach( ); + break; + } + break; + + case KERN_GMM_REG_SUSPENDED: + switch ( gmm_data->kern.detach_cap.detach_type ) + { + case GMMREG_DT_IMSI: + case GMMREG_DT_COMB: + case GMMREG_DT_SIM_REMOVED: + kern_mm_imsi_detach(); + break; + case GMMREG_DT_DISABLE_GPRS: + gmm_data->kern.attach_cap.mobile_class = GMMREG_CLASS_CC; + /* NO break; */ + case GMMREG_DT_GPRS: + /* + * Wait untill GSM is finished + */ + break; + case GMMREG_DT_POWER_OFF: + kern_local_detach( GMMCS_POWER_OFF, FALSE, /* TCS 2.1 */ + GMM_LOCAL_DETACH_PROC_POWER_OFF); + break; + case GMMREG_DT_SOFT_OFF: + kern_local_detach( GMMCS_POWER_OFF, FALSE, /* TCS 2.1 */ + GMM_LOCAL_DETACH_PROC_SOFT_OFF); + break; + default: + TRACE_ERROR ("Unexpected detach type in primitive GMMREG_DETACH_REQ"); + break; + } + break; + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_REG_RESUMING: + TRACE_ERROR ("prim should be saved by pei"); + /* NO break */ + case KERN_GMM_REG_SUSPENDING: + switch ( gmm_data->kern.detach_cap.detach_type ) + { + case GMMREG_DT_IMSI: + case GMMREG_DT_COMB: + case GMMREG_DT_SIM_REMOVED: + gmm_data->kern.suspension_type |= GMM_SUSP_IMSI_DETACH; + break; + case GMMREG_DT_DISABLE_GPRS: + gmm_data->kern.attach_cap.mobile_class = GMMREG_CLASS_CC; + /* NO break; */ + case GMMREG_DT_GPRS: + /* + * Wait untill GSM is finished + */ + break; + case GMMREG_DT_POWER_OFF: + case GMMREG_DT_SOFT_OFF: + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDED); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDED); +#endif + kern_resume_grr_reg(); + break; + default: + TRACE_ERROR ("Unexpected detach type in primitive GMMREG_DETACH_REQ"); + break; + } + break; + + case KERN_GMM_NULL_NO_IMSI: + case KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ: + switch ( gmm_data->kern.detach_cap.detach_type ) + { + case GMMREG_DT_IMSI: + case GMMREG_DT_COMB: + if ( GMM_MM_DEREG != GET_STATE(MM) ) + { + kern_mm_imsi_detach(); + break; + } + /* else NO break;*/ + case GMMREG_DT_SIM_REMOVED: + case GMMREG_DT_GPRS: + { + PALLOC (gmmreg_detach_cnf, GMMREG_DETACH_CNF); + gmmreg_detach_cnf->detach_type = gmm_data->kern.detach_cap.detach_type; + PSEND ( hCommMMI, gmmreg_detach_cnf ); + break; + } + case GMMREG_DT_POWER_OFF: + SET_STATE ( KERN, KERN_GMM_NULL_NO_IMSI ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI ); +#endif + /* NO break*/ + case GMMREG_DT_SOFT_OFF: + kern_mm_imsi_detach_ind (GMMCS_INT_NOT_PRESENT, /* TCS 2.1 */ + GET_STATE(MM)==GMM_MM_DEREG? + MMGMM_DETACH_DONE: + MMGMM_PERFORM_DETACH, + gmm_data->kern.detach_cap.detach_type); + + break; + case GMMREG_DT_DISABLE_GPRS: + gmm_data->kern.attach_cap.mobile_class = GMMREG_CLASS_CC; + { + PALLOC (gmmreg_detach_cnf, GMMREG_DETACH_CNF); + gmmreg_detach_cnf->detach_type = gmm_data->kern.detach_cap.detach_type; + PSEND ( hCommMMI, gmmreg_detach_cnf ); + } + break; + + default: + TRACE_ERROR ("Unexpected detach type in primitive GMMREG_DETACH_REQ"); + break; + } + break; + + + case KERN_GMM_NULL_IMSI: + case KERN_GMM_NULL_PLMN_SEARCH: + case KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ: + switch ( gmm_data->kern.detach_cap.detach_type ) + { + case GMMREG_DT_IMSI: + case GMMREG_DT_COMB: + if ( GMM_MM_DEREG != GET_STATE(MM) ) + { + kern_mm_imsi_detach_ind (GMMCS_INT_NOT_PRESENT, MMGMM_PERFORM_DETACH, + GMMREG_DT_SIM_REMOVED); + + break; + } + /* else NO break;*/ + case GMMREG_DT_GPRS: + { + PALLOC (gmmreg_detach_cnf, GMMREG_DETACH_CNF); + gmmreg_detach_cnf->detach_type = gmm_data->kern.detach_cap.detach_type; + PSEND ( hCommMMI, gmmreg_detach_cnf ); + break; + } + case GMMREG_DT_SOFT_OFF: + SET_STATE ( KERN, KERN_GMM_NULL_IMSI ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI ); +#endif + kern_mm_imsi_detach_ind (GMMCS_INT_NOT_PRESENT, /* TCS 2.1 */ + GET_STATE(MM)==GMM_MM_DEREG? + MMGMM_DETACH_DONE: + MMGMM_PERFORM_DETACH,gmm_data->kern.detach_cap.detach_type); + + break; + case GMMREG_DT_SIM_REMOVED: + case GMMREG_DT_POWER_OFF: + SET_STATE ( KERN, KERN_GMM_NULL_NO_IMSI ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI ); +#endif + kern_mm_imsi_detach_ind (GMMCS_INT_NOT_PRESENT, /* TCS 2.1 */ + GET_STATE(MM)==GMM_MM_DEREG? + MMGMM_DETACH_DONE: + MMGMM_PERFORM_DETACH, + gmm_data->kern.detach_cap.detach_type); + + break; + case GMMREG_DT_DISABLE_GPRS: + gmm_data->kern.attach_cap.mobile_class = GMMREG_CLASS_CC; + { + PALLOC (gmmreg_detach_cnf, GMMREG_DETACH_CNF); + gmmreg_detach_cnf->detach_type = gmm_data->kern.detach_cap.detach_type; + PSEND ( hCommMMI, gmmreg_detach_cnf ); + } + break; + default: + TRACE_ERROR ("Unexpected detach type in primitive GMMREG_DETACH_REQ"); + break; + } + break; + + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + kern_gmmrr_attach_finished(); + + /* NO break; */ + + case KERN_GMM_DEREG_NO_IMSI: + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_DEREG_LIMITED_SERVICE: + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_INITIATED: + + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_DEREG_SUSPENDING: + + switch ( gmm_data->kern.detach_cap.detach_type ) + { + case GMMREG_DT_IMSI: + case GMMREG_DT_COMB: + if ( GMM_MM_DEREG != GET_STATE(MM) ) + { + switch ( GET_STATE( KERN ) ) + { + case KERN_GMM_DEREG_SUSPENDING: + gmm_data->kern.suspension_type |= GMM_SUSP_IMSI_DETACH; + break; + default: + kern_imsi_detach_der_susp (); + break; + } + } + /* NO break;*/ + case GMMREG_DT_GPRS: + { + PALLOC (gmmreg_detach_cnf, GMMREG_DETACH_CNF); + gmmreg_detach_cnf->detach_type = gmm_data->kern.detach_cap.detach_type; + PSEND ( hCommMMI, gmmreg_detach_cnf ); + break; + } + case GMMREG_DT_SOFT_OFF: + kern_local_detach( GMMCS_POWER_OFF, FALSE, GMM_LOCAL_DETACH_PROC_SOFT_OFF); /* TCS 2.1 */ + break; + case GMMREG_DT_POWER_OFF: + kern_local_detach( GMMCS_POWER_OFF, FALSE, GMM_LOCAL_DETACH_PROC_POWER_OFF); /* TCS 2.1 */ + break; + case GMMREG_DT_DISABLE_GPRS: + case GMMREG_DT_SIM_REMOVED: + kern_local_detach( GMMCS_INT_PROTOCOL_ERROR, FALSE, /* TCS 2.1 */ + GMM_LOCAL_DETACH_PROC_ENTER_DEREG ); + break; + default: + TRACE_ERROR ("Unexpected detach type in primitive GMMREG_DETACH_REQ"); + break; + } + break; + + case KERN_GMM_RAU_INITIATED: + case KERN_GMM_RAU_WAIT_FOR_NPDU_LIST: + /* + * DETACH whilst RAU + */ + break; + + default: + TRACE_ERROR( "GMMREG_DETACH_REQ unexpected" ); + break; + } + GMM_RETURN; +} /* kern_gmmreg_detach_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmsms_reg_state_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMSMS_REG_STATE_REQ +| +| MSC: 3.21 Interaction with SMS +| +| Parameters : *gmmsms_reg_state_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmsms_reg_state_req ( T_GMMSMS_REG_STATE_REQ *gmmsms_reg_state_req ) +{ + GMM_TRACE_FUNCTION( "kern_gmmsms_reg_state_req" ); + + PFREE (gmmsms_reg_state_req); + { + PALLOC ( gmmsms_reg_state_cnf, GMMSMS_REG_STATE_CNF ); + gmmsms_reg_state_cnf->radio_priority_level = + gmm_data->kern.attach_cap.sms_radio_priority_level; + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_NULL_NO_IMSI: + case KERN_GMM_NULL_IMSI: + case KERN_GMM_DEREG_NO_IMSI: + case KERN_GMM_REG_SUSPENDED: + case KERN_GMM_REG_RESUMING: + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_DEREG_LIMITED_SERVICE: + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + case KERN_GMM_DEREG_INITIATED: + case KERN_GMM_REG_INITIATED: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + case KERN_GMM_REG_NO_CELL_AVAILABLE: + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_RAU_INITIATED: + + gmmsms_reg_state_cnf->reg_state = SMS_RS_DEREGISTERED; + break; + + case KERN_GMM_REG_NORMAL_SERVICE: + + gmmsms_reg_state_cnf->reg_state = SMS_RS_REGISTERED; + break; + default: + TRACE_ERROR( "GMMSMS_REG_STATE_REQ unexpected" ); + break; + } + PSEND(hCommSMS,gmmsms_reg_state_cnf); + }/* PALLOC*/ + GMM_RETURN; +} /* kern_gmmsms_reg_state_req() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmrr_page_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMRR_PAGE_IND +| +| Parameters : *gmmrr_page_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmrr_page_ind ( T_GMMRR_PAGE_IND *gmmrr_page_ind ) +{ + GMM_TRACE_FUNCTION( "kern_gmmrr_page_ind" ); + + + switch( GET_STATE( KERN ) ) + { + /* + * case GMM-DEREG + * If the MS is not GPRS attached when it receives a paging for + * GPRS services, the MS shall ignore the paging. + * <R.GMM.PAGNGPRS.M.17> + */ + case KERN_GMM_REG_NORMAL_SERVICE: + switch ( gmmrr_page_ind->page_id ) + { + case GMMRR_IMSI: + TRACE_EVENT("paged with IMSI"); + PFREE ( gmmrr_page_ind ); + gmm_data->gu = GU2_NOT_UPDATED; + kern_sim_del_locigprs (); + kern_sim_gmm_update (); + /* + * <R.GMM.PGPIMSI.M.004>, <R.GMM.PGPIMSI.M.005>, + * <R.GMM.PGPIMSI.M.008> + */ + gmm_data->kern.detach_cap.detach_type = GMM_DT_RE_ATTACH; + kern_local_detach( GMMCS_INT_PROTOCOL_ERROR, /* TCS 2.1 */ + FALSE, GMM_LOCAL_DETACH_PROC_RE_ATTACH); + /* + * goto LABEL ATTACH + * + * <R.GMM.PGPIMSI.M.009> + * GMM-DEREG.NORMAL-SERVICE + * + kern_attach_reset(); + kern_attach(); + */ + break; + case GMMRR_PTMSI: + TRACE_EVENT("paged with P-TMSI"); + PFREE ( gmmrr_page_ind ); + { + /* + * <R.GMM.PGPPTMS.M.007> + */ + PALLOC (llgmm_trigger_req, LLGMM_TRIGGER_REQ); + llgmm_trigger_req->trigger_cause = LLGMM_TRICS_PAGE_RESPONSE; + PSEND ( hCommLLC, llgmm_trigger_req ); + break; + } + default: + PFREE ( gmmrr_page_ind ); + TRACE_ERROR( "IMSI or PTMSI page ID expected" ); + break; + } + break; + default: + PFREE ( gmmrr_page_ind ); + TRACE_ERROR( "GMMRR_PAGE_IND unexpected" ); + break; + } + GMM_RETURN; +} /* kern_gmmrr_page_ind() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmrr_cs_page_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMRR_CS_PAGE_IND +| +| Parameters : *gmmrr_cs_page_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmrr_cs_page_ind ( T_GMMRR_CS_PAGE_IND *gmmrr_cs_page_ind ) +{ + GMM_TRACE_FUNCTION( "kern_gmmrr_cs_page_ind" ); + + PFREE ( gmmrr_cs_page_ind ); + + + { + PALLOC ( gmmrr_cs_page_res, GMMRR_CS_PAGE_RES ); + + switch (gmm_data->kern.attach_cap.mobile_class) + { + case GMMRR_CLASS_CG: + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_REJ; + gmmrr_cs_page_res->susp_gprs = GMMRR_NOT_SUSP_GPRS; + break; + +/* PATCH JPS 26.10.02: with class BX, we can have BC in NMOIII */ + case GMMREG_CLASS_BG: + if (GMMRR_NET_MODE_III==gmm_data->kern.sig_cell_info.net_mode) + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_REJ; + gmmrr_cs_page_res->susp_gprs = GMMRR_NOT_SUSP_GPRS; + break; + } + /* NO break; */ + case GMMREG_CLASS_BC: + case GMMREG_CLASS_B: +/* PATCH JPS 26.10.02 END */ + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_REG_RESUMING: + TRACE_ERROR ("prim should be saved by pei"); + break; + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau = TRUE; + /* NO break;*/ + case KERN_GMM_DEREG_NO_IMSI: + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_DEREG_LIMITED_SERVICE: + + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_DEREG_INITIATED: + case KERN_GMM_REG_INITIATED: + if (GMM_MM_DEREG != GET_STATE(MM) + && MMGMM_LIMITED_SERVICE!=gmm_data->kern.sig_cell_info.mm_status + ) + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_CNF; + SET_STATE ( KERN, KERN_GMM_DEREG_SUSPENDED ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_SUSPENDED ); +#endif + } + else + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_REJ; + } + gmmrr_cs_page_res->susp_gprs = GMMRR_NOT_SUSP_GPRS; + break; + case KERN_GMM_REG_SUSPENDED: + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_REG_NO_CELL_AVAILABLE: + if (GMM_MM_DEREG != GET_STATE(MM) + && MMGMM_LIMITED_SERVICE!=gmm_data->kern.sig_cell_info.mm_status) + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_CNF; + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDED ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDED ); +#endif + kern_llgmm_suspend(LLGMM_CALL); + } + else + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_REJ; + } + gmmrr_cs_page_res->susp_gprs = GMMRR_NOT_SUSP_GPRS; + + break; + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + if (GMM_MM_DEREG != GET_STATE(MM) + && MMGMM_LIMITED_SERVICE!=gmm_data->kern.sig_cell_info.mm_status) + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_CNF; + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau = TRUE; + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDED ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDED ); +#endif + kern_llgmm_suspend(LLGMM_CALL); + } + else + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_REJ; + } + gmmrr_cs_page_res->susp_gprs = GMMRR_SUSP_GPRS; + /* + * kern_llgmm_unassign(); + */ + break; + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + /* IOT: Combined RA/LA is accepted with network cause 16 + * MSC temporarily unavailable. MM state is reset to GMM_MM_DEREG + * From the IOT, it was observed that after GMM moves to NMOII, MM + * was able to perform LAU successfully, but not combined RAU. Hence + * in this state we should be able to make and receive CS calls + * Also network is able to reach us through paging */ + if (/*GMM_MM_DEREG != GET_STATE(MM) + && */ MMGMM_LIMITED_SERVICE!=gmm_data->kern.sig_cell_info.mm_status) + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_CNF; + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau = TRUE; + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDED ); + kern_llgmm_suspend(LLGMM_CALL); + } + else + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_REJ; + } + gmmrr_cs_page_res->susp_gprs = GMMRR_SUSP_GPRS; + /* + * kern_llgmm_unassign(); + */ + break; + case KERN_GMM_RAU_INITIATED: + case KERN_GMM_REG_NORMAL_SERVICE: + if (GMM_MM_DEREG != GET_STATE(MM) + && MMGMM_LIMITED_SERVICE!=gmm_data->kern.sig_cell_info.mm_status) + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_CNF; + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDED ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDED ); +#endif + kern_llgmm_suspend(LLGMM_CALL); + } + else + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_REJ; + } + gmmrr_cs_page_res->susp_gprs = GMMRR_SUSP_GPRS; + /* + * kern_llgmm_unassign(); + */ + break; + case KERN_GMM_NULL_IMSI: + /* + * in state KERN_GMM_NULL_IMSI MS is doing a GPRS detach + * and GMM has informed MM to act as GSM only mobile but + * before MM processes the message, GMM receives CS_PAGE_IND + * GMM must reject the CS_PAGE as MM will take care of the + * next CS_PAGE_IND after processing MMGMM_REG_REQ to act as + * GSM only mobile. if GMM accepts the CS_PAGE, GRR will be + * suspended and after coming out of dedicated mode MM will + * not inform GMM about CS connection release and GRR will + * not be resumed. This is to prevent such a race condition. + */ + + TRACE_EVENT("CS Call Received To GMM In GMM_NULL_IMSI state"); + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_REJ; + gmmrr_cs_page_res->susp_gprs = GMMRR_NOT_SUSP_GPRS; + break; + case KERN_GMM_NULL_PLMN_SEARCH: + if (GMM_MM_DEREG != GET_STATE(MM) + && MMGMM_LIMITED_SERVICE!=gmm_data->kern.sig_cell_info.mm_status) + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_CNF; + } + else + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_REJ; + } + gmmrr_cs_page_res->susp_gprs = GMMRR_NOT_SUSP_GPRS; + break; + default: + if (GMM_MM_DEREG != GET_STATE(MM) + && MMGMM_LIMITED_SERVICE!=gmm_data->kern.sig_cell_info.mm_status) + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_CNF; + } + else + { + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_REJ; + } + gmmrr_cs_page_res->susp_gprs = GMMRR_NOT_SUSP_GPRS; + TRACE_ERROR( "GMMRR_CS_PAGE_IND unexpected" ); + break; + } + break; + case GMMRR_CLASS_A: + case GMMRR_CLASS_CC: + gmmrr_cs_page_res->response = GMMRR_CS_PAGE_CNF; + gmmrr_cs_page_res->susp_gprs = GMMRR_NOT_SUSP_GPRS; /* GMM1903A */ + break; + default: + TRACE_ERROR( "unknown MS class"); + break; + } + /* START PATCH UBUOB ISSUE 8379 */ + if (gmmrr_cs_page_res->response == GMMRR_CS_PAGE_CNF) + { + gmm_data->kern.gmmrr_resume_sent = FALSE; + } + /* END PATCH UBUOB ISSUES 8379 */ + PSEND ( hCommGRR, gmmrr_cs_page_res ); + } + GMM_RETURN; +} /* kern_gmmrr_cs_page_ind() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmrr_cr_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMRR_CR_IND +| +| Parameters : *gmmrr_cr_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmrr_cr_ind ( T_GMMRR_CR_IND *gmmrr_cr_ind ) +{ + GMM_TRACE_FUNCTION( "kern_gmmrr_cr_ind" ); + + PFREE ( gmmrr_cr_ind ); + if ( GMM_GRR_STATE_ON == gmm_data->kern.attach_cap.grr_state) + /* + * If GRR is suspended state should be kept. + */ + { + gmm_data->kern.attach_cap.grr_state = GMM_GRR_STATE_CR; + } + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_REG_INITIATED: + case KERN_GMM_RAU_INITIATED: + /* + * store timer value to be able to restart timer after cell reselection + */ + gmm_data->kern.attach_cap.t3310_value=0; + if (VSI_OK == vsi_t_status ( GMM_handle , kern_T3310, &(gmm_data->kern.attach_cap.t3310_value)) + && gmm_data->kern.attach_cap.t3310_value>0) + { + vsi_t_stop ( GMM_handle , kern_T3310); + } + + TRACE_1_INFO ("TIMER t3310 = %dmsec stopped - waiting for CELL_IND",gmm_data->kern.attach_cap.t3310_value); + break; + default: + break; + } + GMM_RETURN; +}/* kern_gmmrr_cr_ind */ + + +/* ++------------------------------------------------------------------------------ +| Function : kern_cgrlc_status_ind (TCS 2.1) ++------------------------------------------------------------------------------ +| Description : Handles the primitive CGRLC_STATUS_IND (TCS 2.1) +| +| Parameters : *cgrlc_status_ind - Ptr to primitive payload (TCS 2.1) +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_cgrlc_status_ind ( T_CGRLC_STATUS_IND *cgrlc_status_ind ) /* TCS 2.1 */ +{ + GMM_TRACE_FUNCTION( "kern_cgrlc_status_ind" ); /* TCS 2.1 */ + + switch (cgrlc_status_ind->failure) /* TCS 2.1 */ + { + case CGRLC_ACCESS_2_NETWORK_NOT_ALLOWED: /* TCS 2.1 */ + TRACE_EVENT ("Access to the network is not allowed"); + break; + case CGRLC_PACKET_ACCESS_FAILURE: /* TCS 2.1 */ + TRACE_EVENT("Failure during packet access procedure, e.g. T3162 expired"); + break; + case CGRLC_RLC_MAC_ERROR: /* TCS 2.1 */ + TRACE_EVENT("T3168 expires during contention resolution"); + break; + case CGRLC_TLLI_MISMATCH: /* TCS 2.1 */ + TRACE_EVENT ("TLLI mismatch has occurred"); + break; + case CGRLC_TBF_ESTABLISHMENT_FAILURE: /* TCS 2.1 */ + TRACE_EVENT ("T3164 expires or failure occurs due to any other reason"); + break; + case CGRLC_RESUMPTION_FAILURE: /* TCS 2.1 */ + TRACE_EVENT ("resumption failure after dedicated mode was left"); + break; + case CGRLC_CONTENTION_RESOLUTION_FAILED: /* TCS 2.1 */ + TRACE_EVENT ("Contantion Resolution has failed"); /* TCS 2.1 */ + break; /* TCS 2.1 */ + default: + TRACE_ERROR ("unknown failure"); + break; + } + + PFREE (cgrlc_status_ind); /* TCS 2.1 */ + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_REG_INITIATED: + case KERN_GMM_RAU_INITIATED: + /************************************************************************ + * MSC: 3.8 Attach + * + * MSC: 3.8.1 Normal Attach + * MSC: 3.8.1.4 Abnormal cases + * MSC: 3.8.1.4.2 b) Lower layer failure before the ATTACH ACCEPT or + * ATTACH REJECT + * message is received + ************************************************************************ + * + *<R.GMM.AGABNORM.M.004>, <R.GMM.LOWERFAIL.M.001> + */ + kern_aac( /*llgmm_status_ind->error_cause*/ 0); + break; + case KERN_GMM_DEREG_INITIATED: + /************************************************************************ + * MSC: 3.9 GPRS detach procedure + * + * MCS: 3.9.3 Abnormal cases + * MSC: 3.9.3.2 b) Lower layer failure + ************************************************************************/ + kern_local_detach ( GMMCS_INT_PROTOCOL_ERROR, FALSE, GMM_LOCAL_DETACH_PROC_ENTER_DEREG); /* TCS 2.1 */ + break; + case KERN_GMM_REG_IMSI_DETACH_INITIATED: + /* + * <R.GMM.DMABNORM.M.021> + */ + /************************************************************************ + * MSC: 3.9 GPRS detach procedure + * + * MCS: 3.9.3 Abnormal cases + * MSC: 3.9.3.2 b) Lower layer failure + ************************************************************************/ + gmm_data->kern.detach_cap.detach_type = GMMREG_DT_IMSI; + kern_local_detach( GMMCS_INT_PROTOCOL_ERROR, FALSE, GMM_LOCAL_DETACH_PROC_ENTER_REG_NORMAL); /* TCS 2.1 */ + break; + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_REG_RESUMING: + case KERN_GMM_REG_SUSPENDED: + TRACE_ERROR( "CGRLC_STATUS_IND unexpected" ); /* TCS 2.1 */ + break; + default: + break; + } + GMM_RETURN; +} /* kern_cgrlc_status_ind() */ /* TCS 2.1 */ +/* ++------------------------------------------------------------------------------ +| Function : kern_llgmm_status_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive LLGMM_STATUS_IND +| +| Parameters : *llgmm_status_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_llgmm_status_ind ( T_LLGMM_STATUS_IND *llgmm_status_ind ) +{ + GMM_TRACE_FUNCTION( "kern_llgmm_status_ind" ); + + PFREE (llgmm_status_ind); + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_REG_INITIATED: + case KERN_GMM_RAU_INITIATED: + /************************************************************************ + * MSC: 3.8 Attach + * + * MSC: 3.8.1 Normal Attach + * MSC: 3.8.1.4 Abnormal cases + * MSC: 3.8.1.4.2 b) Lower layer failure before the ATTACH ACCEPT or + * ATTACH REJECT + * message is received + ************************************************************************ + * + *<R.GMM.AGABNORM.M.004>, <R.GMM.LOWERFAIL.M.001> + */ + kern_aac( /*llgmm_status_ind->error_cause*/ GMMCS_NO_SERVICE); /* TCS 2.1 */ + break; + case KERN_GMM_DEREG_INITIATED: + /************************************************************************ + * MSC: 3.9 GPRS detach procedure + * + * MCS: 3.9.3 Abnormal cases + * MSC: 3.9.3.2 b) Lower layer failure + ************************************************************************/ + kern_local_detach( GMMCS_INT_PROTOCOL_ERROR, FALSE, GMM_LOCAL_DETACH_PROC_ENTER_DEREG); /* TCS 2.1 */ + break; + case KERN_GMM_REG_IMSI_DETACH_INITIATED: + /* + * <R.GMM.DMABNORM.M.021> + */ + /************************************************************************ + * MSC: 3.9 GPRS detach procedure + * + * MCS: 3.9.3 Abnormal cases + * MSC: 3.9.3.2 b) Lower layer failure + ************************************************************************/ + gmm_data->kern.detach_cap.detach_type = GMMREG_DT_IMSI; + kern_local_detach( GMMCS_INT_PROTOCOL_ERROR, FALSE, GMM_LOCAL_DETACH_PROC_ENTER_REG_NORMAL); /* TCS 2.1 */ + + break; + default: + TRACE_ERROR( "LLGMM_STATUS_IND unexpected" ); + break; + } + GMM_RETURN; +} /* kern_llgmm_status_ind() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_llgmm_tlli_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive LLGMM_TLLI_IND +| +| Parameters : *llgmm_status_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_llgmm_tlli_ind ( T_LLGMM_TLLI_IND *llgmm_tlli_ind ) +{ + GMM_TRACE_FUNCTION( "kern_llgmm_tlli_ind" ); + TRACE_1_PARA ("TLLI: 0x%x", llgmm_tlli_ind->new_tlli); + + GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_TLLI); + + switch( GET_STATE( KERN ) ) + { + default: + case KERN_GMM_NULL_NO_IMSI: + case KERN_GMM_NULL_IMSI: + case KERN_GMM_NULL_PLMN_SEARCH: + case KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ: + case KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ: + TRACE_ERROR("LLGMM_TLLI_IND unexpected"); + break; + + case KERN_GMM_DEREG_INITIATED: + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_LIMITED_SERVICE: + case KERN_GMM_DEREG_NO_IMSI: + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_REG_INITIATED: + case KERN_GMM_REG_NO_CELL_AVAILABLE: + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + case KERN_GMM_REG_SUSPENDED: + case KERN_GMM_REG_NORMAL_SERVICE: + case KERN_GMM_RAU_INITIATED: + case KERN_GMM_RAU_WAIT_FOR_NPDU_LIST: + case KERN_GMM_REG_IMSI_DETACH_INITIATED: + case KERN_GMM_REG_RESUMING: + case KERN_GMM_DEREG_SUSPENDING: + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_REG_SUSPENDING: + case KERN_GMM_REG_TEST_MODE: + case KERN_GMM_REG_TEST_MODE_NO_IMSI: + + if ( llgmm_tlli_ind->new_tlli != gmm_data->tlli.current) + { + TRACE_ERROR("TLLI value not expected"); + } + + TRACE_0_OUT_PARA("Unassign Old PTMSI"); + + gmm_data->tlli.old = GMMRR_TLLI_INVALID; + gmm_data->ptmsi.old = GMMRR_TMSI_INVALID; + + GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_TLLI | GMM_DEBUG_PRINT_MASK_PTMSI); + /* + * LLC should know about unassigning itself + */ + kern_gmmrr_assign(); + break; + } + + PFREE (llgmm_tlli_ind); + + GMM_RETURN; +} /* kern_llgmm_tlli_ind() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_sim_gmm_insert_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive SIM_GMM_INSERT_IND +| +| MSC: 3.2 SIM +| +| Parameters : *sim_gmm_insert_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_sim_gmm_insert_ind ( T_SIM_GMM_INSERT_IND *sim_gmm_insert_ind ) +{ + GMM_TRACE_FUNCTION( "kern_sim_gmm_insert_ind" ); + /* + * Set IMSI + */ + + kern_read_imsi ( sim_gmm_insert_ind ) ; + + GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_IMSI); + + kern_read_loc_info (sim_gmm_insert_ind); + + GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_CID); + GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_KERN_ATTACH); + + gmm_data->acc_contr_class = sim_gmm_insert_ind->acc_ctrl.acc[0] * 256 + + sim_gmm_insert_ind->acc_ctrl.acc[1]; + gmm_data->kern.sim_op_mode = sim_gmm_insert_ind->op_mode; + kern_read_kc_cksn (sim_gmm_insert_ind); + + PFREE ( sim_gmm_insert_ind ); + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_NULL_NO_IMSI: + case KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ: + case KERN_GMM_DEREG_NO_IMSI: + /* + * MSC: 3.2 SIM + * + * MSC: 3.2.1 SIM is inserted and valid + */ + /* + * SIM is considered as invalid until SIM removed or switching off + */ + gmm_data->sim_gprs_invalid = FALSE; + /* + * reset the attach attampt counter and the rau attempt counter + * <R.GMM.ATTACH.M.007> + */ + gmm_data->kern.aac = 0; + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_NULL_NO_IMSI: + /* + * <R.GMM.DOTHCASE.M.001> + * SET_STATE ( KERN, KERN_GMM_DEREG_PLMN_SEARCH ); + * + * state GMM-DEREGISTERED.IMSI discribes the state GMM-NULL.IMSI-VALID + */ + + SET_STATE ( KERN, KERN_GMM_NULL_IMSI ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI ); +#endif + break; + case KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ: + SET_STATE (KERN, KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ); +#endif + break; + case KERN_GMM_DEREG_NO_IMSI: + /* + * GMM enters state NULL_IMSI beause GMM is waiting for a new attach + * prim from GACI (COPS=0) + */ + SET_STATE ( KERN, KERN_GMM_NULL_IMSI ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI ); +#endif + break; + default: + TRACE_ERROR( "State unexpected" ); + break; + } + break; + default: + TRACE_ERROR( "SIM_GMM_INSERT_IND unexpected" ); + break; + } + GMM_RETURN; +} /* kern_sim_gmm_insert_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : kern_sim_remove_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive SIM_REMOVE_IND +| +| Parameters : *sim_remove_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_sim_remove_ind ( T_SIM_REMOVE_IND *sim_remove_ind ) +{ + GMM_TRACE_FUNCTION( "kern_sim_remove_ind" ); + + PFREE ( sim_remove_ind ); + + gmm_data->sim_gprs_invalid = TRUE; + gmm_data->kern.detach_cap.detach_type = GMMREG_DT_SIM_REMOVED; + /* + * multiple outstanding SIM_AUTHENTICATION_REQ messages reset the + * counter whenever SIM is removed + */ + gmm_data->kern.auth_cap.last_auth_req_id = NOT_PRESENT_8BIT; + + switch( GET_STATE( KERN ) ) + { + /* + * MSC: 3.2 SIM + * + * MSC: 3.2.2. No SIM present or SIM not valid + * MSC: 3.2.2.2 State GMM-REG + */ + + /* + * MSC: 3.2.2.2.1 Network not reachable + * state GMM_REG + */ + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_REG_RESUMING: + case KERN_GMM_REG_SUSPENDED: + if (GMM_GRR_STATE_SUSPENDED==gmm_data->kern.attach_cap.grr_state) + /* + * wait for MMGMM_CM_RELEASE_IND + */ + { + break; + } + /* NO break;*/ + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_REG_NO_CELL_AVAILABLE: + { + kern_local_detach (GMMCS_SIM_REMOVED, FALSE,GMM_LOCAL_DETACH_PROC_SIM_REMOVED); /* TCS 2.1 */ + break; + } + case KERN_GMM_REG_TEST_MODE: + { + PALLOC (cgrlc_test_end_req, CGRLC_TEST_END_REQ); /* TCS 2.1 */ + SET_STATE (KERN, KERN_GMM_REG_TEST_MODE_NO_IMSI); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_TEST_MODE_NO_IMSI); +#endif + PSEND (hCommGRLC, cgrlc_test_end_req); /* TCS 2.1 */ + } + break; + /* + * MSC: 3.2.2.2.2 Network reachable + * state GMM_REG.NORMAL_SERVICE + */ + case KERN_GMM_RAU_INITIATED: + case KERN_GMM_RAU_WAIT_FOR_NPDU_LIST: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + case KERN_GMM_REG_NORMAL_SERVICE: + /* + * <R.GMM.DSUBFANO.M.003> + */ + + kern_detach (); + break; + /* + * MSC: 3.2 SIM + * + * MSC: 3.2.2. No SIM present or SIM not valid + * MSC: 3.2.2.1 State GMM-DEREG + */ + + /* + * state GMM_DEREG + */ + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_LIMITED_SERVICE: + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + case KERN_GMM_REG_INITIATED: + case KERN_GMM_DEREG_INITIATED: + + kern_mm_imsi_detach_ind ( GMMCS_SIM_REMOVED, MMGMM_PERFORM_DETACH, + gmm_data->kern.detach_cap.detach_type); /* TCS 2.1 */ + /* + * <R.GMM.ODNOIMSI.M.001> + */ + SET_STATE ( KERN, KERN_GMM_DEREG_NO_IMSI ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_NO_IMSI ); +#endif + break; + + case KERN_GMM_NULL_IMSI: + + kern_mm_imsi_detach_ind ( GMMCS_SIM_REMOVED, MMGMM_PERFORM_DETACH, + gmm_data->kern.detach_cap.detach_type ); /* TCS 2.1 */ + /* + * <R.GMM.ODNOIMSI.M.001> + */ + SET_STATE ( KERN, KERN_GMM_NULL_NO_IMSI ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI ); +#endif + break; + + default: + kern_mm_imsi_detach_ind ( GMMCS_SIM_REMOVED, MMGMM_PERFORM_DETACH, + gmm_data->kern.detach_cap.detach_type); /* TCS 2.1 */ + TRACE_ERROR( "SIM_REMOVE_IND unexpected" ); + break; + } + GMM_RETURN; +} /* kern_sim_remove_ind() */ + + +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmrr_suspend_cnf ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMRR_SUSPEND_CNF +| +| GRR confirms that GRR is successful suspended and RR is +| activated. +| +| Parameters : *gmmrr_suspend_cnf - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmrr_suspend_cnf ( T_GMMRR_SUSPEND_CNF *gmmrr_suspend_cnf ) +{ + GMM_TRACE_FUNCTION( "kern_gmmrr_suspend_cnf" ); + PFREE(gmmrr_suspend_cnf); + gmm_data->kern.attach_cap.grr_state = GMM_GRR_STATE_SUSPENDED; + + TRACE_1_PARA ("susp_type: %x", gmm_data->kern.suspension_type); + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_DEREG_SUSPENDING: + SET_STATE (KERN, KERN_GMM_DEREG_SUSPENDED); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_SUSPENDED); +#endif + if(gmm_data->kern.detach_cap.detach_type EQ GMMREG_DT_GPRS) + { + if ( GET_STATE(MM) != GMM_MM_REG_NORMAL_SERVICE) + /* + * The state of MM is forwarded to MMI + */ + { + gmm_data->kern.detach_cap.detach_type = GMMREG_DT_COMB; + } + if ( kern_lau_needed()) + { + /* + * see also kern_enter_der () + */ + kern_gmmreg_detach (gmm_data->kern.detach_cap.detach_type, GMMCS_INT_NOT_PRESENT, + GMMREG_SEARCH_RUNNING, GMMCS_INT_NOT_PRESENT); + } + else + { + kern_gmmreg_detach (gmm_data->kern.detach_cap.detach_type, GMMCS_INT_NOT_PRESENT, + GMMREG_SEARCH_NOT_RUNNING,GMMCS_INT_NOT_PRESENT); + } + } + + kern_call_undone_mm_proc_der(); + break; + + case KERN_GMM_REG_SUSPENDING: + SET_STATE (KERN, KERN_GMM_REG_SUSPENDED); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDED); +#endif + kern_call_undone_mm_proc_reg(); + break; + + case KERN_GMM_NULL_NO_IMSI: + kern_local_detach ( GMMCS_POWER_OFF, /* TCS 2.1 */ + FALSE, GMM_LOCAL_DETACH_PROC_NOTHING); + break; + default: + TRACE_ERROR( "GMMRR_SUSPNED_CNF unexpected" ); + break; + } + GMM_RETURN; +} /* kern_gmmrr_suspend_cnf() */ +/* ++------------------------------------------------------------------------------ +| Function : kern_cgrlc_test_mode_cnf (TCS 2.1) ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMRR_SUSPEND_CNF +| +| GRR confirms that the test mode is finished +| +| Parameters : *cgrlc_test_mode_cnf - Ptr to primitive payload (TCS 2.1) +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_cgrlc_test_mode_cnf ( T_CGRLC_TEST_MODE_CNF *cgrlc_test_mode_cnf ) /* TCS 2.1 */ +{ + GMM_TRACE_FUNCTION( "kern_cgrlc_test_mode_cnf" ); /* TCS 2.1 */ + PFREE (cgrlc_test_mode_cnf); /* TCS 2.1 */ + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_REG_TEST_MODE: + kern_enter_reg_normal(); + break; + case KERN_GMM_REG_TEST_MODE_NO_IMSI: + /* + * <R.GMM.DSUBFANO.M.003> + */ + + gmm_data->kern.detach_cap.detach_type = GMMREG_DT_SIM_REMOVED; + kern_detach (); + break; + default: + TRACE_ERROR( "CGRLC_TEST_MODE_CNF unexpected" ); /* TCS 2.1 */ + break; + } + GMM_RETURN; +} /* kern_cgrlc_test_mode_cnf() */ /* TCS 2.1 */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_lup_needed_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_LUP_NEEDED_IND +| +| MSC: 3.20.8 MMGMM LUP NEEDED IND +| +| Parameters : *mmgmm_lup_needed_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_lup_needed_ind ( T_MMGMM_LUP_NEEDED_IND *mmgmm_lup_needed_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_lup_needed_ind" ); +#ifndef NTRACE + switch (mmgmm_lup_needed_ind->reason) /* TCS 2.1 */ + { + case MMGMM_T3212: + TRACE_EVENT("T3212 has expired"); + break; + case MMGMM_T_ACCEPT: + TRACE_EVENT("T_ACCEPT has expired"); + break; + case MMGMM_IMSI_IN_VLR: + TRACE_EVENT("IMSI unknown in VLR received"); + break; + case MMGMM_RXLEV_JUMP: + TRACE_EVENT("RR indicated an increased RX level"); + break; + case MMGMM_REG_TIMER: + TRACE_EVENT("Registration timer in MM expired"); + break; + default: + TRACE_ERROR("GPRS indicator is out of range"); + break; + } +#endif + switch (GET_STATE( KERN )) + { + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_NULL_NO_IMSI: + case KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ: + case KERN_GMM_NULL_IMSI: + case KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ: + case KERN_GMM_DEREG_INITIATED: + case KERN_GMM_DEREG_NO_IMSI: + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + case KERN_GMM_DEREG_LIMITED_SERVICE: + case KERN_GMM_DEREG_SUSPENDING: + case KERN_GMM_REG_NO_CELL_AVAILABLE: + break; + default: + if( GMMRR_NET_MODE_I==gmm_data->kern.sig_cell_info.net_mode + && MMGMM_T3212==mmgmm_lup_needed_ind->reason) /* TCS 2.1 */ + /* + * <R.GMM.MMGMMONE.M.002>, <R.GMM.MMGMMONE.M.003> + */ + { + PFREE (mmgmm_lup_needed_ind); + GMM_RETURN; + } + break; + } + + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_NULL_NO_IMSI: + case KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ: + case KERN_GMM_NULL_IMSI: + case KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ: + /* + * After deregistration MM will receive mmgmm_reg_req + * automatically + */ + break; + case KERN_GMM_DEREG_NO_IMSI: + /* PLU also if #7 */ + /*NO break;*/ + case KERN_GMM_DEREG_PLMN_SEARCH: + + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_LIMITED_SERVICE: + case KERN_GMM_REG_INITIATED: + SET_STATE ( KERN, KERN_GMM_DEREG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_SUSPENDING ); +#endif + kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_LAU); + break; + + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau = TRUE; + SET_STATE ( KERN, KERN_GMM_DEREG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_SUSPENDING ); +#endif + kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_LAU); + break; + case KERN_GMM_DEREG_INITIATED: + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_REG_SUSPENDED: + case KERN_GMM_REG_RESUMING: + case KERN_GMM_RAU_INITIATED: + case KERN_GMM_RAU_WAIT_FOR_NPDU_LIST: + case KERN_GMM_REG_IMSI_DETACH_INITIATED: + SET_STATE(MM, GMM_MM_REG_UPDATE_NEEDED); + break; + + case KERN_GMM_REG_SUSPENDING: + case KERN_GMM_DEREG_SUSPENDING: + gmm_data->kern.suspension_type |= GMM_SUSP_LAU; + break; + + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau=TRUE; + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDING ); +#endif + kern_llgmm_suspend(LLGMM_CALL); + kern_gmmrr_suspend (GMMRR_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_LAU); + break; + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_REG_NO_CELL_AVAILABLE: + if(gmm_data->kern.gmmrr_resume_sent) + /* + * GMM is waiting for GMMRR_CELL_IND. So I rememmber to attach MM with + * seting mm_imsi_attached to update_needed + */ + { + SET_STATE(MM,GMM_MM_REG_UPDATE_NEEDED); + } + else + { + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDING ); +#endif + kern_llgmm_suspend(LLGMM_CALL); + kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_LAU); + } + break; + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_REG_NORMAL_SERVICE: + if( GMMRR_NET_MODE_I==gmm_data->kern.sig_cell_info.net_mode) + { + kern_rau(); + } + else + { + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDING ); +#endif + kern_llgmm_suspend(LLGMM_CALL); + kern_gmmrr_suspend (GMMRR_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_LAU); + } + break; + case KERN_GMM_REG_TEST_MODE_NO_IMSI: + case KERN_GMM_REG_TEST_MODE: + break; + default: + TRACE_ERROR ("Unexpexcted state"); + break; + } + + PFREE (mmgmm_lup_needed_ind); + GMM_RETURN; +} /* kern_mmgmm_lup_needed_ind() */ + + +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_lup_accept_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_LUP_ACCEPT_IND +| +| MSC: 3.20.3 IMSI attach/detach +| +| Parameters : *mmgmm_lup_accept_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_lup_accept_ind ( T_MMGMM_LUP_ACCEPT_IND *mmgmm_lup_accept_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_lup_accept_ind" ); + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_NULL_PLMN_SEARCH: + case KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ: + case KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ: + case KERN_GMM_NULL_NO_IMSI: + + case KERN_GMM_NULL_IMSI: + case KERN_GMM_DEREG_NO_IMSI: + case KERN_GMM_DEREG_LIMITED_SERVICE: + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_REG_INITIATED: + + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_DEREG_SUSPENDING: + if ( GMMRR_NET_MODE_III==gmm_data->kern.sig_cell_info.net_mode + && GMMREG_CLASS_BC== gmm_data->kern.attach_cap.mobile_class ) + { + kern_mmgmmreg_attach_cnf (GMMREG_AT_IMSI, SEARCH_NOT_RUNNING, (T_MMGMM_REG_CNF*)mmgmm_lup_accept_ind); + } + else + { + kern_mmgmmreg_attach_cnf (GMMREG_AT_IMSI, SEARCH_RUNNING, (T_MMGMM_REG_CNF*)mmgmm_lup_accept_ind); + } + break; + case KERN_GMM_REG_NORMAL_SERVICE: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + case KERN_GMM_REG_NO_CELL_AVAILABLE: + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_DEREG_INITIATED: + case KERN_GMM_RAU_INITIATED: + + case KERN_GMM_REG_RESUMING: + case KERN_GMM_REG_SUSPENDED: + kern_mmgmmreg_attach_cnf (GMMREG_AT_COMB, SEARCH_RUNNING, (T_MMGMM_REG_CNF*)mmgmm_lup_accept_ind); + break; + default: + TRACE_ERROR ("Unexpexcted state"); + break; + } + PFREE ( mmgmm_lup_accept_ind ); + GMM_RETURN; +} /* kern_mmgmm_lup_accept_ind() */ +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_lup_accept_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_INFO_IND +| +| MSC: 3.20.6 MM Information +| +| Parameters : *mmgmm_info_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_info_ind ( T_MMGMM_INFO_IND *mmgmm_info_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_info_ind" ); + { + PPASS (mmgmm_info_ind, gmmreg_info_ind, GMMREG_INFO_IND); + PSEND ( hCommMMI, gmmreg_info_ind ); + } + GMM_RETURN; +} /* kern_mmgmm_info_ind() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_sim_authentication_cnf ++------------------------------------------------------------------------------ +| Description : The function kern_sim_authentication_cnf +| +| Parameters : *sim_authentication_cnf - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_sim_authentication_cnf ( T_SIM_AUTHENTICATION_CNF * + sim_authentication_cnf ) +{ + GMM_TRACE_FUNCTION( "kern_sim_authentication_cnf" ); + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_REG_NORMAL_SERVICE: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + case KERN_GMM_REG_NO_CELL_AVAILABLE: + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_REG_INITIATED: + case KERN_GMM_DEREG_INITIATED: + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + case KERN_GMM_RAU_INITIATED: + case KERN_GMM_REG_IMSI_DETACH_INITIATED: + /* + * PATCH ubuob 19.7.02: multiple outstanding AUTHENTICATION REQ messages + * reduce the count of outstanding requests + */ + + /* + * only use this SIM answer if there are no other outstanding SIM_AUTHENTICATION_REQ messages! + */ + + if (gmm_data->kern.auth_cap.last_auth_req_id == sim_authentication_cnf->req_id) + + + if (gmm_data->kern.auth_cap.last_auth_req_id == sim_authentication_cnf->req_id) + { + MCAST (authentication_and_ciphering_response, + AUTHENTICATION_AND_CIPHERING_RESPONSE); + authentication_and_ciphering_response->a_c_reference_number + .a_c_reference_number_value + = gmm_data->kern.auth_cap.a_c_reference_number; + + authentication_and_ciphering_response + ->v_authentication_parameter_sres = TRUE; + authentication_and_ciphering_response + ->authentication_parameter_sres.sres_value.l_sres_value = MAX_SRES*8; + authentication_and_ciphering_response + ->authentication_parameter_sres.sres_value.o_sres_value = 0; + memcpy (authentication_and_ciphering_response-> + authentication_parameter_sres.sres_value.b_sres_value, + sim_authentication_cnf->sres, MAX_SRES); + + memcpy ( gmm_data->kern.auth_cap.kc, sim_authentication_cnf->kc, + MAX_KC ) ; + +#ifdef GMM_TCS4 + gmm_data->kern.auth_cap.last_auth_req_id = NOT_PRESENT_8BIT; +#endif + + PFREE (sim_authentication_cnf); + /* + * <R.GMM.AUTH_RES.M.006> + */ + { + PALLOC ( llgmm_assign_req, LLGMM_ASSIGN_REQ ); + llgmm_assign_req->old_tlli = LLGMM_TLLI_INVALID; + llgmm_assign_req->new_tlli = gmm_data->tlli.current; + if (NO_KEY== gmm_data->kern.auth_cap.cksn) + { + memset (llgmm_assign_req->llgmm_kc.key, 0x0, MAX_KC); + } + else + { + memcpy ( llgmm_assign_req->llgmm_kc.key, gmm_data->kern.auth_cap.kc, MAX_KC ); + } + llgmm_assign_req->ciphering_algorithm + = gmm_data->kern.auth_cap.ciphering_algorithm; + + PSEND ( hCommLLC, llgmm_assign_req ); + } + + + if (IMEISV_REQUESTED == gmm_data->kern.auth_cap.imeisv_requested) + { + authentication_and_ciphering_response->v_gmobile_identity = TRUE; + kern_get_imeisv ( + &authentication_and_ciphering_response->gmobile_identity); + } + else + { + authentication_and_ciphering_response->v_gmobile_identity = FALSE; + } + sig_kern_tx_data_req (CURRENT_TLLI,AUTHENTICATION_AND_CIPHERING_RESPONSE); + } + else + { + PFREE (sim_authentication_cnf); + /* + * mutliple authentication request problem occurred!!!! + * ignore this SIM answer because another request has already been sent to + * the SIM again and this overwrote the A&C reference number + */ + TRACE_0_INFO ("error: Authentication received twice, SIM ignored"); + } + /* end patch ubuob */ + break; + + default: + + PFREE (sim_authentication_cnf); + TRACE_1_INFO ("state: %x", GET_STATE( KERN )); + TRACE_ERROR("A&C RES unexpected"); + break; + } + GMM_RETURN; +} /* kern_sim_authentication_cnf() */ + + +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_nreg_cnf ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_NREG_CNF +| +| MSC: 3.20.3 IMSI attach/detach +| +| Parameters : *mmgmm_nreg_cnf - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_nreg_cnf ( T_MMGMM_NREG_CNF *mmgmm_nreg_cnf ) +{ + UBYTE detach_type; + GMM_TRACE_FUNCTION( "kern_mmgmm_nreg_cnf" ); + + if (gmm_data->kern.attach_cap.mobile_class_changed + && GMM_GRR_STATE_ON == gmm_data->kern.attach_cap.grr_state) + { + gmm_data->kern.attach_cap.mobile_class_changed=FALSE; + kern_gmmrr_enable(); + } + + switch (mmgmm_nreg_cnf->detach_cause) /* TCS 2.1 */ + { + case CS_SIM_REM: + detach_type = GMMREG_DT_SIM_REMOVED; + TRACE_EVENT ("SIM is removed"); + break; + case CS_POW_OFF: + detach_type = GMMREG_DT_POWER_OFF; + TRACE_EVENT ("Power is switched off"); + break; + case CS_SOFT_OFF: + detach_type = GMMREG_DT_SOFT_OFF; + TRACE_EVENT ("Power is soft switched off"); + break; + case CS_DISABLE: + detach_type = GMMREG_DT_IMSI; + TRACE_EVENT ("GSM switched off"); + break; + default: + detach_type = GMMREG_DT_POWER_OFF; + TRACE_EVENT ("unknown detach type in MMGMM_NREG_CNF"); + break; + } + SET_STATE( MM, GMM_MM_DEREG ); + sig_kern_sync_set_mm_state(MMGMM_CELL_SELECTED); + + if (gmm_data->sim_gprs_invalid && gmm_data->kern.cell_id.lac == GMMREG_LA_INVALID && mmgmm_nreg_cnf->detach_cause == CS_SIM_REM) + { + switch ( GET_STATE (KERN) ) + { + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_DEREG_SUSPENDED: + SET_STATE(KERN,KERN_GMM_DEREG_NO_IMSI); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_NO_IMSI); +#endif + break; + case KERN_GMM_REG_IMSI_DETACH_INITIATED: + kern_enter_reg_normal(); + break; + case KERN_GMM_DEREG_NO_IMSI: + SET_STATE(KERN,KERN_GMM_NULL_NO_IMSI); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI); +#endif + break; + default: + break; + } + PFREE ( mmgmm_nreg_cnf ); + GMM_RETURN; + } + switch ( GET_STATE (KERN) ) + { + case KERN_GMM_DEREG_PLMN_SEARCH: + switch(mmgmm_nreg_cnf->detach_cause) /* TCS 2.1 */ + { + case CS_SOFT_OFF: + case CS_POW_OFF: + kern_gmmreg_detach (GMMREG_DT_POWER_OFF, + GMMCS_POWER_OFF, /* TCS 2.1 */ + SEARCH_NOT_RUNNING, + GMMCS_POWER_OFF); + break; + case CS_SIM_REM: + SET_STATE(KERN,KERN_GMM_DEREG_NO_IMSI); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_NO_IMSI); +#endif + kern_gmmreg_detach (GMMREG_DT_SIM_REMOVED, + GMMCS_SIM_REMOVED, /* TCS 2.1 */ + SEARCH_NOT_RUNNING, + GMMCS_SIM_REMOVED); + break; + default: + kern_gmmreg_detach (GMMREG_DT_COMB, + /* START UBUOB PATCH ISSUE 8381 */ + GMMCS_NET_CAUSE_NOT_PRESENT, /* TCS 2.1 */ + /* END UBUOB PATCH ISSUE 8381 */ + SEARCH_RUNNING, + GMMCS_NET_CAUSE_NOT_PRESENT); + kern_mm_activate_rr(); + break; + } + + break; + + case KERN_GMM_NULL_NO_IMSI: + case KERN_GMM_NULL_IMSI: + /* + * POWER OFF + */ + if( CS_DISABLE==mmgmm_nreg_cnf->detach_cause) /* TCS 2.1 */ + { + detach_type=GMMREG_DT_IMSI; + } + kern_gmmreg_detach (detach_type, + gmm_data->kern.detach_cap.error_cause, /* TCS 2.1 */ + SEARCH_NOT_RUNNING, + gmm_data->kern.detach_cap.error_cause); + + break; + case KERN_GMM_DEREG_SUSPENDED: + switch(mmgmm_nreg_cnf->detach_cause) /* TCS 2.1 */ + { + case CS_SOFT_OFF: + kern_gmmreg_detach (GMMREG_DT_SOFT_OFF, + GMMCS_POWER_OFF, /* TCS 2.1 */ + SEARCH_NOT_RUNNING, + GMMCS_POWER_OFF); + break; + case CS_POW_OFF: + kern_gmmreg_detach (GMMREG_DT_POWER_OFF, + GMMCS_POWER_OFF, /* TCS 2.1 */ + SEARCH_NOT_RUNNING, + GMMCS_POWER_OFF); + break; + case CS_SIM_REM: + SET_STATE(KERN,KERN_GMM_DEREG_NO_IMSI); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_NO_IMSI); +#endif + kern_gmmreg_detach (GMMREG_DT_SIM_REMOVED, + GMMCS_SIM_REMOVED, /* TCS 2.1 */ + SEARCH_NOT_RUNNING, + GMMCS_SIM_REMOVED); + break; + default: + /* ACI can not handle SEARCH RUNNING to show GSM detached */ + if (GMMRR_NET_MODE_III==gmm_data->kern.sig_cell_info.net_mode + && GMMREG_CLASS_BG== gmm_data->kern.attach_cap.mobile_class ) + { + kern_gmmreg_detach (GMMREG_DT_COMB, + GMMCS_NET_CAUSE_NOT_PRESENT, /* TCS 2.1 */ + SEARCH_RUNNING, + GMMCS_NET_CAUSE_NOT_PRESENT); + } + else + { + kern_gmmreg_detach (GMMREG_DT_COMB, + GMMCS_NET_CAUSE_NOT_PRESENT, /* TCS 2.1 */ + SEARCH_NOT_RUNNING, + GMMCS_NET_CAUSE_NOT_PRESENT); + } + break; + } + kern_call_undone_mm_proc_der(); + break; + case KERN_GMM_REG_SUSPENDED: + switch(mmgmm_nreg_cnf->detach_cause) /* TCS 2.1 */ + { + case CS_SOFT_OFF: + kern_gmmreg_detach (GMMREG_DT_SOFT_OFF, + GMMCS_POWER_OFF, /* TCS 2.1 */ + SEARCH_NOT_RUNNING, + GMMCS_POWER_OFF); + break; + case CS_POW_OFF: + kern_gmmreg_detach (GMMREG_DT_POWER_OFF, + GMMCS_POWER_OFF, /* TCS 2.1 */ + SEARCH_NOT_RUNNING, + GMMCS_POWER_OFF); + break; + case CS_DISABLE: + if (GMMREG_DT_IMSI == gmm_data->kern.detach_cap.detach_type) + { + kern_gmmreg_detach (GMMREG_DT_IMSI, + GMMCS_NET_CAUSE_NOT_PRESENT, /* TCS 2.1 */ + SEARCH_NOT_RUNNING, + GMMCS_NET_CAUSE_NOT_PRESENT); + break; + } + /* + * else: wait for gprs detach to be finished + * FALLTHROUGH + */ + case CS_SIM_REM: + if (GMMRR_NET_MODE_III!=gmm_data->kern.sig_cell_info.net_mode) + { + + /* + * Wait until GPRS is deregistered + */ + break; + } + /* + * else NO break; + * we are ms class BG and have switched off GSM + */ + default: + kern_gmmreg_detach (GMMREG_DT_IMSI, + GMMCS_NET_CAUSE_NOT_PRESENT, /* TCS 2.1 */ + SEARCH_NOT_RUNNING, + GMMCS_NET_CAUSE_NOT_PRESENT); + break; + } + kern_call_undone_mm_proc_reg(); + break; + case KERN_GMM_REG_IMSI_DETACH_INITIATED: + kern_enter_reg_normal(); + if(GMMRR_NET_MODE_I!=gmm_data->kern.sig_cell_info.net_mode) + /* + * In NMO I gmmreg_detach_cnf was sent before requesting + * mmgmm_net_req + */ + { + kern_gmmreg_detach (detach_type, + GMMCS_NET_CAUSE_NOT_PRESENT, /* TCS 2.1 */ + GMMREG_SEARCH_NOT_RUNNING, + GMMCS_NET_CAUSE_NOT_PRESENT); + } + break; + case KERN_GMM_REG_NORMAL_SERVICE: + break; + case KERN_GMM_DEREG_NO_IMSI: + SET_STATE(KERN,KERN_GMM_NULL_NO_IMSI); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI); +#endif + kern_gmmreg_detach (detach_type, + GMMCS_INT_NOT_PRESENT, /* TCS 2.1 */ + GMMREG_SEARCH_NOT_RUNNING, + GMMCS_INT_NOT_PRESENT); + break; + default: + TRACE_ERROR( "MMGMM_NREG_CNF unexpected" ); + break; + } + PFREE ( mmgmm_nreg_cnf ); + +#ifdef TRACE_FUNC +#ifdef IDENTATION + if (gmm_data->deep<=0) { + /* + * after power off deep is set to 0 in kern_init so we need here normal + * return + */ + return; + } + else + { + GMM_RETURN; + } +#endif +#endif +} /* kern_mmgmm_nreg_cnf() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_auth_rej_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_AUTH_REJ_IND +| +| Parameters : *mmgmm_auth_rej_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_auth_rej_ind ( T_MMGMM_AUTH_REJ_IND *mmgmm_auth_rej_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_auth_rej_ind" ); + PFREE (mmgmm_auth_rej_ind); + + gmm_data->sim_gprs_invalid = TRUE; + gmm_data->kern.detach_cap.detach_type = GMMREG_DT_SIM_REMOVED; + kern_sim_del_locigprs (); + gmm_data->gu = GU3_ROAMING_NOT_ALLOWED; + kern_sim_gmm_update (); + + GMM_RETURN; +} /* kern_mmgmm_auth_rej_ind() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_t3212_val_ind +| +| Description : Handles the primitive MMGMM_T3212_VAL _IND +| +| Parameters : *mmgmm_t3212_val_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_t3212_val_ind ( T_MMGMM_T3212_VAL_IND *mmgmm_t3212_val_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_t3212_val_ind" ); + +#ifdef REL99 + switch (gmm_data->kern.sig_cell_info.sgsnr_flag)/*!gmm_data->release99 =>old code*/ /* TCS 4.0 */ + { + default: + case PS_SGSN_UNKNOWN: + case PS_SGSN_98_OLDER: +#endif + + /* + * see GSM04.08 ch. 11.2.2 NOTE 4 + */ + gmm_data->kern.t3302_val = mmgmm_t3212_val_ind->t3212_val; + /* + * Boeser Hack wegen Faulheit, signal should be taken + */ + gmm_data->sync.mm_cell_info.t3212_val = gmm_data->kern.t3302_val; + +#ifdef REL99 + break; + case PS_SGSN_99_ONWARDS: + break; + } +#endif + + PFREE ( mmgmm_t3212_val_ind ); + GMM_RETURN; +} /* kern_mmgmm_t3212_val_ind() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_cm_establish_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_CM_ESTABLISH_IND +| +| Parameters : *mmgmm_cm_establish_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_cm_establish_ind ( T_MMGMM_CM_ESTABLISH_IND *mmgmm_cm_establish_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_cm_establish_ind" ); + + PFREE ( mmgmm_cm_establish_ind ); + + if (gmm_data->kern.gmmrr_resume_sent) + { + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + GMM_RETURN; + } + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_REG_RESUMING: + TRACE_ERROR ("prim should be saved"); + break; + case KERN_GMM_DEREG_SUSPENDING: + case KERN_GMM_REG_SUSPENDING: + gmm_data->kern.suspension_type |= GMM_SUSP_CALL; + break; + + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_NULL_IMSI: + kern_mm_cm_establish_res (MMGMM_ESTABLISH_OK); + break; + case KERN_GMM_DEREG_LIMITED_SERVICE: + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_DEREG_INITIATED: + case KERN_GMM_REG_INITIATED: + switch (gmm_data->kern.attach_cap.mobile_class) + { + case GMMREG_CLASS_A: + if (GMMRR_NET_MODE_III == gmm_data->kern.sig_cell_info.net_mode) + { + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + } + else + { + kern_mm_cm_establish_res (MMGMM_ESTABLISH_OK); + } + break; + case GMMREG_CLASS_CG: + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + break; + case GMMREG_CLASS_BG: + if (GMMRR_NET_MODE_III == gmm_data->kern.sig_cell_info.net_mode) + { + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + break; + } + /* NO break */ + case GMMREG_CLASS_B: + case GMMREG_CLASS_BC: + /* START PATCH UBUOB ISSUE 8278 */ + switch (GET_STATE (KERN)) + { + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau = TRUE; + break; + default: + break; + } + /* END PATCH UBUOB ISSUE 8278 */ + + if (GMM_MM_DEREG != GET_STATE(MM)) + { + SET_STATE ( KERN, KERN_GMM_DEREG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_SUSPENDING ); +#endif + /* START PATCH UBUOB ISSUE 8781 */ + /* kern_gmmreg_suspend (GMMREG_CS_CALL); */ + /* END PATCH UBUOB ISSUE 8781 */ + kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_ABNORMAL_RELEASE, GMM_SUSP_CALL); + vsi_t_stop(GMM_handle, kern_T3321); + } + else + { + SET_STATE( KERN, KERN_GMM_DEREG_SUSPENDING); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_SUSPENDING); +#endif + /* + * kern_llgmm_unassign(); + */ + kern_llgmm_suspend(LLGMM_CALL); + kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_ABNORMAL_RELEASE, GMM_SUSP_CALL); + } + break; + default: + TRACE_ERROR( "unknown MS class"); + break; + } + break; + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + case KERN_GMM_REG_NO_CELL_AVAILABLE: + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_RAU_INITIATED: + switch (gmm_data->kern.attach_cap.mobile_class) + { + case GMMREG_CLASS_A: + kern_mm_cm_establish_res (MMGMM_ESTABLISH_OK); + break; + case GMMREG_CLASS_CG: + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + break; + case GMMREG_CLASS_BG: + if (GMMRR_NET_MODE_III == gmm_data->kern.sig_cell_info.net_mode) + { + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + break; + } + /* NO break; */ + case GMMREG_CLASS_B: + case GMMREG_CLASS_BC: + /* START PATCH UBUOB ISSUE 8278 */ + switch (GET_STATE (KERN)) + { + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau = TRUE; + break; + default: + break; + } + /* END PATCH UBUOB ISSUE 8278 */ + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDING ); +#endif + kern_llgmm_suspend(LLGMM_CALL); + kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_ABNORMAL_RELEASE, GMM_SUSP_CALL); + break; + default: + TRACE_ERROR( "unknown MS class"); + break; + } + break; + + case KERN_GMM_REG_NORMAL_SERVICE: + switch (gmm_data->kern.attach_cap.mobile_class) + { + case GMMREG_CLASS_A: + kern_mm_cm_establish_res (MMGMM_ESTABLISH_OK); + break; + case GMMREG_CLASS_CG: + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + break; + case GMMREG_CLASS_BG: + if (GMMRR_NET_MODE_III == gmm_data->kern.sig_cell_info.net_mode) + { + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + break; + } + /* NO break; */ + case GMMREG_CLASS_B: + case GMMREG_CLASS_BC: + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDING ); +#endif + kern_llgmm_suspend(LLGMM_CALL); + kern_gmmrr_suspend (GMMRR_SUSP_GPRS, GMMRR_ABNORMAL_RELEASE, GMM_SUSP_CALL); + break; + default: + TRACE_ERROR( "unknown MS class"); + break; + } + break; + case KERN_GMM_REG_SUSPENDED: + switch (gmm_data->kern.attach_cap.mobile_class) + { + case GMMREG_CLASS_A: + kern_mm_cm_establish_res (MMGMM_ESTABLISH_OK); + break; + case GMMREG_CLASS_CG: + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + break; + case GMMREG_CLASS_BG: + if (GMMRR_NET_MODE_III == gmm_data->kern.sig_cell_info.net_mode) + { + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + break; + } + /* NO break; */ + case GMMREG_CLASS_B: + case GMMREG_CLASS_BC: + /* + * call is rejected because MM may establish the call by itself. + * When state REG_RESUMING will be defined than GMM will return OK. + * In case of waiting for GMMRR_CELL_IND after GMMRR_RESUME_REQ + * the mobile will run into a dead lock situation otherwise. + */ + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + break; + default: + TRACE_ERROR( "unknown MS class"); + break; + } + break; + case KERN_GMM_DEREG_NO_IMSI: + case KERN_GMM_NULL_NO_IMSI: + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + break; + default: + kern_mm_cm_establish_res (MMGMM_ESTABLISH_REJECT); + TRACE_1_INFO ("state: %x", GET_STATE( KERN )); + TRACE_ERROR( "MMGMM_CM_ESTABLISH_IND unexpected" ); + break; + } + GMM_RETURN; +} /* kern_mm_cm_establish_ind() */ +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_cm_emergency_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_CM_EMERGENCY_IND +| +| Parameters : *mmgmm_cm_emergency_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_cm_emergency_ind ( T_MMGMM_CM_EMERGENCY_IND *mmgmm_cm_emergency_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_cm_emeregncy_ind" ); + + PFREE ( mmgmm_cm_emergency_ind ); + + if (GMMREG_CLASS_A == gmm_data->kern.attach_cap.mobile_class + && GMMRR_NET_MODE_III != gmm_data->kern.sig_cell_info.net_mode) + { + kern_mm_cm_emergency_res (MMGMM_ESTABLISH_OK); + GMM_RETURN; + } + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_REG_RESUMING: + TRACE_ERROR ("prim should be saved"); + break; + + case KERN_GMM_DEREG_SUSPENDING: + case KERN_GMM_REG_SUSPENDING: + gmm_data->kern.suspension_type |= GMM_SUSP_EM_CALL; + break; + case KERN_GMM_DEREG_SUSPENDED: + case KERN_GMM_REG_SUSPENDED: + case KERN_GMM_NULL_IMSI: + case KERN_GMM_NULL_NO_IMSI: + case KERN_GMM_NULL_PLMN_SEARCH: + case KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ: + case KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ: + kern_mm_cm_emergency_res (MMGMM_ESTABLISH_OK); + break; + case KERN_GMM_DEREG_NO_IMSI: + if (gmm_data->kern.detach_cap.gmmreg) + /* + * The mobile is switching off this moment. Thera are no power anymore + */ + { + kern_mm_cm_emergency_res (MMGMM_ESTABLISH_REJECT); + } + break; + + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_DEREG_LIMITED_SERVICE: + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_INITIATED: + case KERN_GMM_REG_INITIATED: + SET_STATE ( KERN, KERN_GMM_DEREG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_SUSPENDING ); +#endif + kern_llgmm_suspend(LLGMM_CALL); + kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_ABNORMAL_RELEASE, GMM_SUSP_EM_CALL); + break; + case KERN_GMM_RAU_WAIT_FOR_NPDU_LIST: + case KERN_GMM_REG_IMSI_DETACH_INITIATED: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + case KERN_GMM_REG_NO_CELL_AVAILABLE: + case KERN_GMM_REG_LIMITED_SERVICE: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_RAU_INITIATED: + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDING); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDING); +#endif + kern_llgmm_suspend(LLGMM_CALL); + kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_ABNORMAL_RELEASE, GMM_SUSP_EM_CALL); + break; + case KERN_GMM_REG_NORMAL_SERVICE: + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDING ); +#endif + /* + * kern_llgmm_unassign(); + */ + kern_llgmm_suspend(LLGMM_CALL); + kern_gmmrr_suspend (GMMRR_SUSP_GPRS, GMMRR_ABNORMAL_RELEASE, GMM_SUSP_EM_CALL); + break; + default: + TRACE_ERROR( "MMGMM_CM_EMERGENCY_IND unexpected" ); + break; + } + GMM_RETURN; +} /* kern_mm_cm_emergency_ind() */ +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_cm_release_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_CM_RELEASE_IND +| +| Parameters : *mmgmm_cm_release_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_cm_release_ind ( T_MMGMM_CM_RELEASE_IND *mmgmm_cm_release_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_cm_release_ind" ); + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_REG_SUSPENDED: + /* + * resume with cell_ind + */ + if (MMGMM_RESUMPTION_OK!=mmgmm_cm_release_ind->resumption) + { + TRACE_EVENT("Para: resumption failure: RAU needed"); + SET_STATE(GU,GU_UPDATE_NEEDED); + } + else + { + TRACE_EVENT("OPar: resumption OK."); + } + PFREE ( mmgmm_cm_release_ind ); + kern_call_undone_mm_proc_reg(); + break; + case KERN_GMM_DEREG_SUSPENDED: + PFREE ( mmgmm_cm_release_ind ); + kern_call_undone_mm_proc_der(); + break; + case KERN_GMM_DEREG_SUSPENDING: + case KERN_GMM_REG_SUSPENDING: + gmm_data->kern.suspension_type &= ~ (GMM_SUSP_CALL|GMM_SUSP_EM_CALL); + + PFREE ( mmgmm_cm_release_ind ); + break; + + default: + + if (GMMREG_CLASS_A!=gmm_data->kern.attach_cap.mobile_class) + { + TRACE_ERROR( "MMGMM_CM_RELEASE_IND unexpected" ); + } + PFREE ( mmgmm_cm_release_ind ); + break; + } + GMM_RETURN; +} /* kern_mm_cm_release_ind() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_plmn_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_PLMN_IND +| +| MSC: 3.20 MM Interface +| MSC: 3.20.2 Network selection +| +| Parameters : *mmgmm_plmn_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_plmn_ind ( T_MMGMM_PLMN_IND *mmgmm_plmn_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_plmn_ind" ); + { + PPASS (mmgmm_plmn_ind, gmmreg_plmn_ind, GMMREG_PLMN_IND); + PSEND ( hCommMMI, gmmreg_plmn_ind ); + } + GMM_RETURN; +} /* kern_mm_plmn_ind() */ + + +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmreg_attach_req ++------------------------------------------------------------------------------ +| Description : Handles the the primitive GMMREG_ATTACH_REQ +| +| This signal passed the attach_type from MMI to +| the service KERN +| +| MSC : 3.4 MMI-initiated normal/combined GPRS attach +| +| Parameters : *gmmreq_attach_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmreg_attach_req ( T_GMMREG_ATTACH_REQ *gmmreg_attach_req ) +{ + U8 attach_type_changed = FALSE; + GMM_TRACE_FUNCTION( "kern_gmmreg_attach_req" ); + TRACE_EVENT ("hp_gmm_24473#1#24473"); /* TCS 2.1 */ + + /* Changes for Boot Time Speedup. GMM will get dummy GMMREG_ATTACH_REQ indicating QUICK_REG. + * GMM will send MMGMM_REG_REQ indicating QUICK_REG. No need to process this request as it is + * dummy request and GMM will get other GMMREG_ATTACH_REQ indicating NORMAL_REG + */ + if (gmmreg_attach_req->bootup_act EQ QUICK_REG) + { + kern_mm_reg_req (REG_GPRS_INACTIVE, QUICK_REG); + return ; + } + vsi_t_stop ( GMM_handle, kern_T3302); + sig_kern_rdy_stop_t3302_req(); + gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau = FALSE; + /* + * attach_cap.gmmreg sets the caller of the attach procedure to MMI + */ + gmm_data->kern.attach_cap.gmmreg = TRUE; + gmm_data->kern.detach_cap.gmmreg = FALSE; + + gmm_data->kern.attach_cap.service_mode = gmmreg_attach_req->service_mode; + + + if (SERVICE_MODE_LIMITED == gmm_data->kern.attach_cap.service_mode) + { + /* + * I expect that limited service means emergency call over GSM only + * CLASS_CC can be set, because service mode is changed via + * GMMREG_ATTACH_REQ only, so that the wanted mobile class is giveb again + */ + gmm_data->kern.attach_cap.mobile_class = GMMREG_CLASS_CC; + gmm_data->kern.attach_cap.attach_type = GMMREG_AT_IMSI; + + } + else + { + /* + *PATCH TB 26/10/02 < + * Inform GRR of the new MS class + */ + attach_type_changed = + ( gmm_data->kern.attach_cap.mobile_class != gmmreg_attach_req->mobile_class + || gmm_data->kern.attach_cap.attach_type!= gmmreg_attach_req->attach_type); + + if (GMM_GRR_STATE_OFF != gmm_data->kern.attach_cap.grr_state + && (gmm_data->kern.attach_cap.mobile_class != gmmreg_attach_req->mobile_class)) + { + if (GMMRR_NET_MODE_III==gmm_data->kern.sig_cell_info.net_mode) + { + gmm_data->kern.attach_cap.mobile_class_changed = TRUE; + gmm_data->kern.attach_cap.mobile_class = gmmreg_attach_req->mobile_class; + /* + * inform GRR after switch (mmgmm_nreg_cnf xor kern _enter_der) + * kern_gmmrr_enable(); + */ + } + else + { + gmm_data->kern.attach_cap.mobile_class = gmmreg_attach_req->mobile_class; + kern_gmmrr_enable(); + } + } + /* PATCH TB 26/10/02 > */ + + + gmm_data->kern.attach_cap.mobile_class = gmmreg_attach_req->mobile_class; + /* + * if MMI wants to detach, then detach is expected or class change + */ + gmm_data->kern.attach_cap.attach_type = + (GMMREG_CLASS_CG == gmmreg_attach_req->mobile_class? + GMMREG_AT_GPRS: + gmm_data->kern.attach_cap.attach_type|gmmreg_attach_req->attach_type); + + } + + + + #ifndef NTRACE + switch (gmmreg_attach_req->service_mode) + { + case SERVICE_MODE_LIMITED: + TRACE_EVENT ("Limited Service"); + break; + case SERVICE_MODE_FULL: + TRACE_EVENT ("Full Service"); + break; + default: + TRACE_ERROR ("wrong Service requested"); + } + switch ( gmm_data->kern.attach_cap.mobile_class ) + { + case GMMREG_CLASS_CC: + TRACE_0_PARA("MS class CC"); + break; + case GMMREG_CLASS_CG: + TRACE_0_PARA("MS class CG"); + break; + case GMMREG_CLASS_B: + TRACE_0_PARA("MS class B"); + break; + case GMMREG_CLASS_BG: + TRACE_0_PARA("MS class BG"); + break; + case GMMREG_CLASS_BC: + TRACE_0_PARA("MS class BC"); + break; + case GMMREG_CLASS_A: + TRACE_0_PARA("MS class A"); + break; + default: + TRACE_ERROR ("unknown mobile class"); + break; + } + switch (gmm_data->kern.attach_cap.attach_type) + { + case GMMREG_AT_IMSI: + TRACE_0_PARA("GSM only attach"); + break; + case GMMREG_AT_GPRS: + TRACE_0_PARA("GPRS attach"); + break; + case GMMREG_AT_COMB: + TRACE_0_PARA("GSM and GPRS attach"); + break; + default: + TRACE_ERROR ("unknown attach type"); + TRACE_1_PARA("%d",gmm_data->kern.attach_cap.attach_type); + break; + } +#endif + + if (gmm_data->sim_gprs_invalid + && GMMREG_CLASS_CG == gmm_data->kern.attach_cap.mobile_class) + /* + * i.e. error cause 7: gprs not allowed + */ + { + PREUSE(gmmreg_attach_req,gmmreg_attach_rej,GMMREG_ATTACH_REJ ); + gmmreg_attach_rej->detach_type = + (GMM_MM_REG_NORMAL_SERVICE == GET_STATE(MM)?GMMREG_DT_GPRS:GMMREG_DT_COMB), + gmmreg_attach_rej->search_running = GMMREG_SEARCH_NOT_RUNNING, + gmmreg_attach_rej->cause = GMMCS_GPRS_NOT_ALLOWED; /* TCS 2.1 */ + gmmreg_attach_rej->service = GMMCS_GPRS_NOT_ALLOWED; + gmm_data->kern.attach_cap.gmmreg = FALSE; + + PSEND ( hCommMMI, gmmreg_attach_rej ); + GMM_RETURN; + } + + + PFREE ( gmmreg_attach_req ); + + switch( GET_STATE( KERN ) ) + { + /* + * GMM-DEREGISTERED + */ + case KERN_GMM_DEREG_RESUMING: + case KERN_GMM_REG_RESUMING: + TRACE_ERROR ("prim should be saved"); + break; + + case KERN_GMM_DEREG_PLMN_SEARCH: + case KERN_GMM_DEREG_LIMITED_SERVICE: + case KERN_GMM_DEREG_NO_CELL_AVAILABLE: + case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH: + + case KERN_GMM_DEREG_SUSPENDING: + case KERN_GMM_DEREG_SUSPENDED: + if (SERVICE_MODE_LIMITED == gmm_data->kern.attach_cap.service_mode) + { + SET_STATE ( KERN, KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ); +#endif + kern_gmmrr_disable(); + kern_mm_activate_mm(); + break; + } + + if (GMMREG_CLASS_CC==gmm_data->kern.attach_cap.mobile_class + || GMMREG_AT_IMSI== gmm_data->kern.attach_cap.attach_type) + { + SET_STATE ( KERN, KERN_GMM_NULL_IMSI ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI ); +#endif + kern_gmmrr_disable(); + kern_mm_activate_mm(); + if ( GMM_MM_REG_NORMAL_SERVICE == GET_STATE(MM) ) + { + kern_gmmreg_attach_cnf( GMMREG_AT_IMSI); + } + break; + } + + switch ( gmm_data->kern.attach_cap.mobile_class ) + { + case GMMREG_CLASS_CG: + if ( GMM_MM_DEREG != GET_STATE(MM) ) + { + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_DEREG_SUSPENDED: + /* + * Case GMMREG_CLASS_CG. + * The detach procedure for cs is only possible after receiving + * GMMRR_CELL_IND + */ + break; + case KERN_GMM_DEREG_SUSPENDING: + gmm_data->kern.suspension_type |=GMM_SUSP_IMSI_DETACH; + break; + default: + if (kern_lai_changed() ) + { + SET_STATE ( KERN, KERN_GMM_DEREG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_SUSPENDING ); +#endif + kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_LAU); + } + else + { + kern_imsi_detach_der_susp(); + } + GMM_RETURN; + } + } + break; + default: + break; + } + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_DEREG_SUSPENDED: + gmm_data->kern.attach_cap.mm_lau_attempted=TRUE; + gmm_data->kern.suspension_type &= ~GMM_SUSP_LAU; + break; + case KERN_GMM_DEREG_SUSPENDING: + gmm_data->kern.suspension_type |=GMM_SUSP_LAU; + break; + default: + { + kern_mm_reg_req (REG_CELL_SEARCH_ONLY, NORMAL_REG); + } + break; + + } + break; + case KERN_GMM_NULL_PLMN_SEARCH: + if (SERVICE_MODE_LIMITED == gmm_data->kern.attach_cap.service_mode) + { + SET_STATE (KERN,KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ); +#endif + kern_mm_activate_mm (); + break; + } + + if (GMMREG_CLASS_CC==gmm_data->kern.attach_cap.mobile_class + || GMMREG_AT_IMSI== gmm_data->kern.attach_cap.attach_type) + { + kern_mm_activate_mm (); + break; + } + + + switch ( gmm_data->kern.attach_cap.mobile_class ) + { + case GMMREG_CLASS_CG: + if ( GMM_MM_DEREG != GET_STATE(MM) ) + { + SET_STATE(KERN, KERN_GMM_DEREG_PLMN_SEARCH); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_PLMN_SEARCH); +#endif + /* + * MM enters autmaticly gprs cell search mode so that GMM + * need not to send mmgmm_reg_req (cell_search_only) + */ + kern_mm_imsi_detach(); + } + else + { + SET_STATE ( KERN, KERN_GMM_DEREG_PLMN_SEARCH ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_PLMN_SEARCH ); +#endif + kern_mm_activate_rr(); + } + break; + default: + /* + * class A and B + */ + SET_STATE ( KERN, KERN_GMM_DEREG_PLMN_SEARCH ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_PLMN_SEARCH ); +#endif + kern_mm_activate_rr(); + break; + } + break; + /* + * GPRS will be enabled + */ + case KERN_GMM_NULL_IMSI: + if (SERVICE_MODE_LIMITED == gmm_data->kern.attach_cap.service_mode) + { + SET_STATE (KERN,KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ); +#endif + kern_mm_activate_mm (); + break; + } + if (GMM_MM_DEREG != GET_STATE(MM) + && GMMREG_CLASS_CC == gmm_data->kern.attach_cap.mobile_class) + { + TRACE_EVENT ("GMMREG_ATTACH_REQ has been come twice and is ignored!"); + /* + * the funcion is not alled because mm_plmn is used. + */ + + kern_gmmreg_attach_cnf(GMMREG_AT_IMSI); + gmm_data->kern.attach_cap.gmmreg = FALSE; + + break; + } + /* NO break */ + case KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ: + if (SERVICE_MODE_LIMITED != gmm_data->kern.attach_cap.service_mode) + { + gmm_data->kern.sig_cell_info.gmm_status = GMMRR_SERVICE_UNKNOWN ; /* Initalize gmm status value */ + switch ( gmm_data->kern.attach_cap.mobile_class ) + { + case GMMREG_CLASS_CC: + if (KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ==GET_STATE(KERN) + || GMM_MM_DEREG == GET_STATE(MM)) + { + SET_STATE ( KERN, KERN_GMM_NULL_PLMN_SEARCH ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_PLMN_SEARCH ); +#endif + kern_mm_activate_mm(); + } + else + { + SET_STATE(KERN,KERN_GMM_NULL_IMSI); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI); +#endif + kern_gmmreg_attach_cnf( GMMREG_AT_IMSI); + } + break; + case GMMREG_CLASS_CG: + if ( GMM_MM_DEREG != GET_STATE(MM) ) + { + switch(GET_STATE(KERN)) + { + case KERN_GMM_NULL_IMSI: + SET_STATE ( KERN, KERN_GMM_DEREG_PLMN_SEARCH); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_PLMN_SEARCH); +#endif + /* + * MM enters autmaticly gprs cell search mode so that GMM + * need not to send mmgmm_reg_req (cell_search_only) + */ + kern_mm_imsi_detach(); + break; + default: + break; + } + } + else + { + SET_STATE ( KERN, KERN_GMM_DEREG_PLMN_SEARCH ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_PLMN_SEARCH ); +#endif + kern_mm_activate_rr(); + } + break; + default: + /* + * class A and B + */ + if (GMMREG_AT_IMSI== gmm_data->kern.attach_cap.attach_type) + { + SET_STATE ( KERN, KERN_GMM_NULL_PLMN_SEARCH ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_PLMN_SEARCH ); +#endif + kern_mm_activate_mm(); + } + else + { + SET_STATE ( KERN, KERN_GMM_DEREG_PLMN_SEARCH ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_DEREG_PLMN_SEARCH ); +#endif + + kern_mm_activate_rr(); + } + break; + } + } + break; + /* end case KERN_GMM_NULL_IMSI */ + + case KERN_GMM_DEREG_NO_IMSI: + /* + * this state is not necessary, it is the same as NULL_NO_IMSI + * and will be romoved soon + */ + + if (SERVICE_MODE_LIMITED == gmm_data->kern.attach_cap.service_mode) + { + SET_STATE (KERN,KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ); +#endif + } + else + { + SET_STATE (KERN,KERN_GMM_NULL_NO_IMSI); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI); +#endif + } + kern_gmmrr_disable(); + kern_mm_activate_mm(); + break; + + case KERN_GMM_NULL_NO_IMSI: + /* + * Attach Rejected for the first time to enable POWER_OFF + */ + if (SERVICE_MODE_LIMITED == gmm_data->kern.attach_cap.service_mode) + { + SET_STATE (KERN,KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ); +#endif + } + kern_mm_activate_mm(); + break; + case KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ: + if ( SERVICE_MODE_LIMITED != gmm_data->kern.attach_cap.service_mode) + { + SET_STATE (KERN,KERN_GMM_NULL_NO_IMSI); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI); +#endif + } + kern_mm_activate_mm(); + break; + case KERN_GMM_REG_NORMAL_SERVICE: + if (SERVICE_MODE_LIMITED == gmm_data->kern.attach_cap.service_mode) + { + kern_l_sim_rem_reg(); + } + else + { + switch ( gmm_data->kern.attach_cap.mobile_class ) + { + case GMMREG_CLASS_CC: + if ( GMM_MM_REG_NORMAL_SERVICE == GET_STATE(MM) ) + { + kern_gmmreg_attach_cnf ( GMMREG_AT_IMSI ); + } + kern_disable(); + break; + case GMMREG_CLASS_CG: + if (GMM_MM_DEREG != GET_STATE(MM)) + { + if (kern_lai_changed() ) + { + switch (gmm_data->kern.sig_cell_info.net_mode) + { + case GMMRR_NET_MODE_I: + kern_rau(); + break; + default: + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDING ); +#endif + kern_llgmm_suspend(LLGMM_CALL); + kern_gmmrr_suspend (GMMRR_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_LAU); + break; + } + } + else + { + switch (gmm_data->kern.sig_cell_info.net_mode) + { + case GMMRR_NET_MODE_I: + gmm_data->kern.detach_cap.detach_type = GMMREG_DT_IMSI; + kern_detach(); + break; + default: + kern_imsi_detach_reg_susp(); + break; + } + } + GMM_RETURN; + } + /* + * <R.GMM.AGACCEPT.M.027>, + * <R.GMM.PATTCNF.M.001> + */ + else + { + kern_gmmreg_attach_cnf ( GMMREG_AT_GPRS ); + } + break; + default: + if (attach_type_changed) + { + /* + * class A and B + */ + if ( GMM_MM_REG_NORMAL_SERVICE == GET_STATE(MM) ) + { + kern_gmmreg_attach_cnf ( GMMREG_AT_COMB ); + } + else + { + /* + * Combined RAU procedure is established + * if GPRS is attached and IMSI should attached + */ + + kern_rau(); + } + } + else + { + kern_mm_reg_req (REG_CELL_SEARCH_ONLY, NORMAL_REG); + } + break; + } + } + break; + case KERN_GMM_REG_SUSPENDED: + case KERN_GMM_REG_SUSPENDING: + if (SERVICE_MODE_LIMITED == gmm_data->kern.attach_cap.service_mode) + { + kern_l_sim_rem_reg_lim (); + break; + } + /* + * Attach requests in suspended mode will be handled after resumption + * by triggering form GRR with GMMRR_CELL_IND + */ + break; + + case KERN_GMM_REG_NO_CELL_AVAILABLE: + case KERN_GMM_REG_LIMITED_SERVICE: + if (SERVICE_MODE_LIMITED == gmm_data->kern.attach_cap.service_mode) + { + kern_l_sim_rem_reg_lim (); + break; + } + /* NO break */ + case KERN_GMM_RAU_INITIATED: + case KERN_GMM_REG_INITIATED: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + + if (SERVICE_MODE_LIMITED == gmm_data->kern.attach_cap.service_mode) + { + kern_l_sim_rem_reg (); + } + else + { + switch ( gmm_data->kern.attach_cap.mobile_class ) + { + case GMMREG_CLASS_CC: + + gmm_data->kern.detach_cap.detach_type = GMMREG_DT_DISABLE_GPRS; + + kern_local_detach( GMMCS_INT_PROTOCOL_ERROR, FALSE, GMM_LOCAL_DETACH_PROC_ENTER_NULL_IMSI); /* TCS 2.1 */ + if ( GMM_MM_REG_NORMAL_SERVICE == GET_STATE(MM) ) + { + kern_gmmreg_attach_cnf ( GMMREG_AT_IMSI ); + } + kern_enter_der(); + break; + case GMMREG_CLASS_CG: + if (GMM_MM_DEREG != GET_STATE(MM)) + { + if (kern_lai_changed() ) + { + switch(GET_STATE(KERN)) + { + case KERN_GMM_REG_NO_CELL_AVAILABLE: + case KERN_GMM_RAU_INITIATED: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM: + case KERN_GMM_REG_ATTEMPTING_TO_UPDATE: + kern_llgmm_suspend(LLGMM_CALL); + break; + default: + break; + } + + SET_STATE ( KERN, KERN_GMM_REG_SUSPENDING ); +#ifdef FF_EM_MODE + EM_GMM_SET_STATE(KERN_GMM_REG_SUSPENDING ); +#endif + + + kern_gmmrr_suspend (GMMRR_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_LAU); + } + else + { + kern_imsi_detach_reg_susp(); + } + GMM_RETURN; + } + else + /* + * <R.GMM.AGACCEPT.M.027>, + * <R.GMM.PATTCNF.M.001> + */ + { + if (KERN_GMM_REG_INITIATED!=GET_STATE(KERN)) + { + kern_gmmreg_attach_cnf ( GMMREG_AT_GPRS ); + } + } + break; + default: + + { + kern_mm_reg_req (REG_CELL_SEARCH_ONLY, NORMAL_REG); + } + break; + } + } + break; + default: + TRACE_ERROR( "GMMREG_ATTACH_REQ unexpected" ); + break; + + } + GMM_RETURN; +} /* kern_gmmreg_attach_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : kern_gmmsm_sequence_res ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMSM_SEQENCE_RES +| +| Parameters : *gmmsm_sequence_res - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +#ifdef GMM_TCS4 +GLOBAL void kern_gmmsm_sequence_res ( T_MMPM_SEQUENCE_RES *gmmsm_sequence_res ) +#else +GLOBAL void kern_gmmsm_sequence_res ( T_GMMSM_SEQUENCE_RES *gmmsm_sequence_res ) +#endif +{ + GMM_TRACE_FUNCTION( "kern_gmmsm_sequence_res" ); + + + switch( GET_STATE( KERN ) ) + { + case KERN_GMM_RAU_WAIT_FOR_NPDU_LIST: + { + int i=0; + MCAST (routing_area_update_complete, ROUTING_AREA_UPDATE_COMPLETE); + routing_area_update_complete->v_receive_n_pdu_number_list = TRUE; + routing_area_update_complete->receive_n_pdu_number_list. + c_receive_n_pdu_number_list_val = gmmsm_sequence_res->c_npdu_list; + + for (i=0;i<routing_area_update_complete->receive_n_pdu_number_list.c_receive_n_pdu_number_list_val;i++) + { + routing_area_update_complete + ->receive_n_pdu_number_list.receive_n_pdu_number_list_val[i] + .nsapi + = gmmsm_sequence_res->npdu_list[i].nsapi; + + routing_area_update_complete + ->receive_n_pdu_number_list.receive_n_pdu_number_list_val[i] + .receive_n_pdu_number_val + + = gmmsm_sequence_res->npdu_list[i].receive_n_pdu_number_val; + + } + + PFREE (gmmsm_sequence_res); + kern_rau_complete (gmm_data->kern.attach_cap.result_type); + + break; + } + default: + PFREE (gmmsm_sequence_res); + TRACE_ERROR( "GMMSM_SEQUENCE_RES received in an unusual state." ); + break; + } + GMM_RETURN; +} /* kern_gmmsm_sequence_res() */ + + /*TI DK primitive*/ +#ifdef REL99 +/*+------------------------------------------------------------------------------ +| Function : kern_gmmsm_pdp_status_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMSM_PDP_STATUS_REQ +| +| Parameters : *gmmsm_pdp_status_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_gmmsm_pdp_status_req ( T_MMPM_PDP_CONTEXT_STATUS_REQ *gmmsm_pdp_status_req ) + +{ + GMM_TRACE_FUNCTION( "kern_gmmsm_pdp_status_req" ); + + /* Store the data in context */ + gmm_data->kern.attach_cap.pdp_context_status = + gmmsm_pdp_status_req->nsapi_set; + + GMM_RETURN; +} /* kern_gmmsm_pdp_status_req() */ +#endif + +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_ciphering_ind ++------------------------------------------------------------------------------ +| Description : forwards the ciphering indicator of GSM to MMI +| +| Parameters : *mmgmm_ciphering_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_ciphering_ind ( T_MMGMM_CIPHERING_IND *mmgmm_ciphering_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_ciphering_ind" ); + { + PALLOC (gmmreg_ciphering_ind, GMMREG_CIPHERING_IND); + gmmreg_ciphering_ind->gsm_ciph = mmgmm_ciphering_ind->ciph; + /* + * do not include the ciphering status of gprs purposely to have the + * behaviour for GSM and for GPRS (do not remember the status of the other!) + */ + gmmreg_ciphering_ind->gprs_ciph = CIPH_NA; + PFREE ( mmgmm_ciphering_ind ); + PSEND ( hCommMMI, gmmreg_ciphering_ind ); + } + GMM_RETURN; +} /* kern_mmgmm_ciphering_ind() */ +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_tmsi_ind ++------------------------------------------------------------------------------ +| Description : forwards the TMSI received in MM to GMM +| +| Parameters : *mmgmm_tmsi_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_tmsi_ind ( T_MMGMM_TMSI_IND *mmgmm_tmsi_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_tmsi_ind" ); + gmm_data->tmsi = mmgmm_tmsi_ind->tmsi; + TRACE_1_PARA("TMSI %x", gmm_data->tmsi ); + PFREE ( mmgmm_tmsi_ind ); + GMM_RETURN; +} /* kern_mmgmm_ciphering_ind() */ + +/* ++------------------------------------------------------------------------------ +| Function : kern_mmgmm_ahplmn_ind ++------------------------------------------------------------------------------ +| Description : forwards the ahplmn indicator to MMI +| +| Parameters : *mmgmm_ahplmn_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void kern_mmgmm_ahplmn_ind ( T_MMGMM_AHPLMN_IND *mmgmm_ahplmn_ind ) +{ + GMM_TRACE_FUNCTION( "kern_mmgmm_ahplmn_ind" ); + { + PPASS (mmgmm_ahplmn_ind, gmmreg_ahplmn_ind, GMMREG_AHPLMN_IND); + PSEND ( hCommMMI, gmmreg_ahplmn_ind ); + } + GMM_RETURN; +} /* kern_mmgmm_ahplmn_ind() */