FreeCalypso > hg > fc-magnetite
view src/g23m-gprs/gmm/gmm_kernp.c @ 673:62a5285e014a
Lorekeeping: allow tpudrv-leonardo.lib on Leonardo/Tango
Back in 2015 the Mother's idea was to produce a FreeCalypso development
board that would be a clone of TI Leonardo, including the original
quadband RFFE; one major additional stipulation was that this board
needed to be able to run original unmodified TCS211-20070608 firmware
with all blobs intact, with only minimal binary patches to main.lib
and tpudrv.lib. The necessary patched libs were produced at that time
in the tcs211-patches repository.
That plan was changed and we produced FCDEV3B instead, with Openmoko's
triband RFFE instead of Leonardo quadband, but when FC Magnetite started
in 2016, a TPUDRV_blob= provision was still made, allowing the possibility
of patching OM's tpudrv.lib for a restored Leonardo RFFE.
Now in 2020 we have FC Tango which is essentially a verbatim clone of
Leonardo core, including the original quadband RFFE. We have also
deblobbed our firmware so much that we have absolutely no real need
for a blob version of tpudrv.lib - but I thought it would be neat to put
the ancient TPUDRV_blob= mechanism (classic config) to its originally
intended use, just for the heck of it.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 29 May 2020 03:55:36 +0000 |
parents | 219afcfc6250 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | 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() */