FreeCalypso > hg > fc-magnetite
diff src/g23m-gprs/gmm/gmm_syncp.c @ 183:219afcfc6250
src/g23m-gprs: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 13 Oct 2016 04:24:13 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-gprs/gmm/gmm_syncp.c Thu Oct 13 04:24:13 2016 +0000 @@ -0,0 +1,586 @@ +/* ++----------------------------------------------------------------------------- +| Project : GPRS (8441) +| Modul : gmm_syncp.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 : ++----------------------------------------------------------------------------- +*/ + +#ifndef GMM_SYNCP_C +#define GMM_SYNCP_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 get the gdebug print function */ + +#include "gmm_kerns.h" /* to get signals */ +#include "gmm_syncf.h" + + +/* ++------------------------------------------------------------------------------ +| Function : sync_tsync ++------------------------------------------------------------------------------ +| Description : Handles expiry of timer TSYNC. This function is called from +| pei_primitive(). +| Timeout for waiting of GMMRR_CELL_IND or MMGMM_ACTIVATE_IND +| or MMGMM_NREG_IND +| Parameters : none +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sync_tsync (void) +{ + GMM_TRACE_FUNCTION( "sync_tsync" ); + TRACE_0_INFO("TIMEOUT TSYNC expired"); + + switch( GET_STATE( SYNC ) ) + { + case SYNC_WAIT_FOR_GPRS: + SET_STATE ( SYNC, SYNC_IDLE ); + sync_send_mm_cell_info(); + break; + case SYNC_WAIT_FOR_GSM: + SET_STATE ( SYNC, SYNC_IDLE ); + sync_send_cell_info(); + break; + case SYNC_IDLE: + default: + TRACE_ERROR("TSYNC expired in wrong state"); + sync_send_cell_info(); + break; + } + GMM_RETURN; +} /* sync_tsync */ + +/* ++------------------------------------------------------------------------------ +| Function : sync_gmmrr_cell_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive GMMRR_CELL_IND +| +| Parameters : *gmmrr_cell_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sync_gmmrr_cell_ind (T_GMMRR_CELL_IND * gmmrr_cell_ind) +{ + +#ifdef REL99 + /*The flag value is initialized to 0(CL_SGSN_REL_98_OR_OLDER). */ + U8 temp_sgsnr_flag = PS_SGSN_98_OLDER; /* TCS 4.0 */ +#endif + + GMM_TRACE_FUNCTION( "sync_gmmrr_cell_ind" ); +#ifdef GMM_TCS4 + TRACE_12_PARA("%s, %s,%x%x%x, %x%x%x, NMO: %d, lac %x, rac %x, cid %x", /* TCS 4.0 */ + (RT_GPRS==gmmrr_cell_ind->cell_info.rt?"GPRS":"EDGE"), /* TCS 4.0 */ + GMMRR_SERVICE_FULL == gmmrr_cell_ind->cell_info.service_state?"service":(GMMRR_SERVICE_LIMITED== gmmrr_cell_ind->cell_info.service_state?"limited service":"NO GPRS service"), + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mcc[0], + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mcc[1], + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mcc[2], + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mnc[0], + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mnc[1], + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mnc[2], + gmmrr_cell_ind->cell_info.net_mode+1, + gmmrr_cell_ind->cell_info.cell_env.rai.lac, + gmmrr_cell_ind->cell_info.cell_env.rai.rac, + gmmrr_cell_ind->cell_info.cell_env.cid); +#else + TRACE_11_PARA("%s,%x%x%x, %x%x%x, NMO: %d, lac %x, rac %x, cid %x", + GMMRR_SERVICE_FULL == gmmrr_cell_ind->cell_info.service_state?"service":(GMMRR_SERVICE_LIMITED== gmmrr_cell_ind->cell_info.service_state?"limited service":"NO GPRS service"), + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mcc[0], + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mcc[1], + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mcc[2], + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mnc[0], + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mnc[1], + gmmrr_cell_ind->cell_info.cell_env.rai.plmn.mnc[2], + gmmrr_cell_ind->cell_info.net_mode+1, + gmmrr_cell_ind->cell_info.cell_env.rai.lac, + gmmrr_cell_ind->cell_info.cell_env.rai.rac, + gmmrr_cell_ind->cell_info.cell_env.cid); +#endif + +#ifdef REL99 + /* During initialiazation sgsnr_flag should be initialized to + * the value 0 (CL_SGSN_REL_98_OR_OLDER) + */ + /* The function getSGSNRelease is implemented by RR layer. It + * returns the current SGSN release flag - CL_SGSN_REL_98_OR_OLDER + * or CL_SGSN_REL_99_ONWARDS + */ + + temp_sgsnr_flag = cl_nwrl_get_sgsn_release(); /* TCS 4.0 */ + TRACE_1_OUT_PARA ("SGSNR_FLAG is >>>>: %x", temp_sgsnr_flag); /* TCS 4.0 */ + /* CL can return three values. SGSN release can be R98, + * R99 or unknown. In case of SGSN release unknown + * we assume the value R98 and proceed. + */ + if(PS_SGSN_99_ONWARDS != temp_sgsnr_flag) + { + temp_sgsnr_flag = PS_SGSN_98_OLDER; + } + + /*Store the flag in context*/ + gmm_data->sync.sig_cell_info.sgsnr_flag = temp_sgsnr_flag; /* TCS 4.0 */ +#endif + + gmm_data->sync.grr_cell_info = gmmrr_cell_ind->cell_info; + PFREE (gmmrr_cell_ind); + + GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_CID); + + gmm_data->sync.mm_cell_info.gprs_indicator=MMGMM_GPRS_SUPP_YES; + gmm_data->sync.sig_cell_info.gmmrr_cell_ind_received = TRUE; + + switch( GET_STATE( SYNC ) ) + { + + case SYNC_IDLE: + /* + * + */ + if ( sync_is_cid_equal () ) + { + /* + * CELL IND in response to RESUME REQ + */ + sync_send_cell_info(); + } + else + { + /* + * Cell Info does not match, synchronize with ACTIVATE IND + */ + SET_STATE ( SYNC, SYNC_WAIT_FOR_GSM ); + /* + * Timer Supervision + */ + TRACE_EVENT ( "Info: START: TSYNC" ); + vsi_t_start ( GMM_handle , sync_TSYNC, TSYNC ); + } + break; + + case SYNC_WAIT_FOR_GPRS: + /* + * Stop Timer ACTIVATE SYNC + */ + TRACE_EVENT ( "Info: STOP: TSYNC" ); + vsi_t_stop ( GMM_handle, sync_TSYNC); + + if ( sync_is_cid_equal() ) + { + /* + * As expected + */ + SET_STATE ( SYNC, SYNC_IDLE ); + sync_send_cell_info(); + } + else + { + /* + * Cell Info does not match, wait for ACTIVATE IND + */ + SET_STATE ( SYNC, SYNC_WAIT_FOR_GSM ); + /* + * Timer Supervision + */ + TRACE_EVENT ( "Info: START: TSYNC" ); + vsi_t_start ( GMM_handle , sync_TSYNC, TSYNC ); + } + break; + case SYNC_WAIT_FOR_GSM: + /* + * CELL IND again? Should not happen; timer runs already... + */ + TRACE_ERROR (" CELL_IND repeatedly received "); + break; + + default: + TRACE_ERROR ("GMMRR_CELL_IND wrong SYNC state"); + break; + } + GMM_RETURN; +} /* sync_gmmrr_cell_ind */ + +/* ++------------------------------------------------------------------------------ +| Function : sync_mmgmm_activate_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_ACTIVATE_IND +| +| Parameters : *mmgmm_activate_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sync_mmgmm_activate_ind (T_MMGMM_ACTIVATE_IND *mmgmm_activate_ind) +{ + GMM_TRACE_FUNCTION( "sync_mmgmm_activate_ind" ); + +#ifndef NTRACE + switch (mmgmm_activate_ind->gprs_indicator) + { + case MMGMM_GPRS_SUPP_NO: + TRACE_EVENT("IPar: NO GPRS Service!"); + break; + case MMGMM_GPRS_SUPP_YES: + TRACE_EVENT("IPar: cell supports GPRS"); + break; + default: + TRACE_ERROR("indicator is out of range"); + break; + } + + switch (mmgmm_activate_ind->status) + { + case MMGMM_LIMITED_SERVICE: + + TRACE_EVENT("IPar: limited service"); + break; + case MMGMM_FULL_SERVICE: + TRACE_EVENT("IPar: full service"); + break; + case MMGMM_CELL_SELECTED: + TRACE_EVENT("IPar: cell changed"); + break; + case MMGMM_WAIT_FOR_UPDATE: + TRACE_EVENT("IPar: LUP REQ from MM"); + break; + default: + TRACE_ERROR("unknown MM status"); + } +#endif + + gmm_data->sync.mm_cell_info.cid = mmgmm_activate_ind->cid; + gmm_data->sync.mm_cell_info.gprs_indicator = mmgmm_activate_ind->gprs_indicator; + gmm_data->sync.mm_cell_info.lac = mmgmm_activate_ind->lac; + gmm_data->sync.mm_cell_info.plmn = mmgmm_activate_ind->plmn; + gmm_data->sync.mm_cell_info.status = mmgmm_activate_ind->status; + gmm_data->sync.sig_cell_info.mm_status = gmm_data->sync.mm_cell_info.status; + gmm_data->sync.mm_cell_info.t3212_val = mmgmm_activate_ind->t3212_val; + PFREE (mmgmm_activate_ind); + + GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_CID); + + switch( GET_STATE( SYNC ) ) + { + case SYNC_IDLE: + + if (sync_is_cid_equal()) + { + /* + * signal cell info + */ + sync_send_cell_info(); + } + else + { + /* + * synchronize with CELL IND + */ + SET_STATE ( SYNC, SYNC_WAIT_FOR_GPRS ); + /* + * Timer Supervision + */ + TRACE_EVENT ( "Info: START: TSYNC" ); + vsi_t_start ( GMM_handle , sync_TSYNC, TSYNC ); + } + break; + + case SYNC_WAIT_FOR_GSM: + /* + * Stop Timer CELL SYNC + */ + TRACE_EVENT ( "Info: STOP: TSYNC" ); + vsi_t_stop ( GMM_handle, sync_TSYNC); + + if (sync_is_cid_equal()) + { + /* + * As expected + */ + SET_STATE ( SYNC, SYNC_IDLE ); + sync_send_cell_info(); + } + else + { + /* + * Cell Info does not match, wait for CELL IND + */ + SET_STATE ( SYNC, SYNC_WAIT_FOR_GPRS ); + /* + * Timer Supervision + */ + TRACE_EVENT ( "Info: START: TSYNC" ); + vsi_t_start ( GMM_handle , sync_TSYNC, TSYNC ); + } + break; + + case SYNC_WAIT_FOR_GPRS: + /* + * Again, should not happen! Timer runs already.. + */ + TRACE_ERROR (" ACTIVATE_IND repeatedly received "); + break; + + default: + TRACE_ERROR ("MMGMM_ACTIVATE_IND wrong SYNC state"); + break; + } + GMM_RETURN; +} /* sync_mmgmm_activate_ind */ + +/* ++------------------------------------------------------------------------------ +| Function : sync_mmgmm_nreg_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_NREG_IND +| +| Parameters : *mmgmm_nreg_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sync_mmgmm_nreg_ind (T_MMGMM_NREG_IND *mmgmm_nreg_ind) +{ + GMM_TRACE_FUNCTION( "sync_mmgmm_nreg_ind" ); + + switch( GET_STATE( SYNC ) ) + { + + case SYNC_WAIT_FOR_GSM: + /* + * NREG IND received while waiting for ACTIVATE IND + */ + TRACE_EVENT ( "Info: STOP: TSYNC" ); + vsi_t_stop ( GMM_handle , sync_TSYNC); + /* + * handle as if ACTIVATE IND received + */ + SET_STATE ( SYNC, SYNC_IDLE ); + /* + * + */ + switch (mmgmm_nreg_ind->service) /* TCS 2.1 */ + { + case NREG_NO_SERVICE: /* TCS 2.1 */ + gmm_data->sync.mm_cell_info.lac = GMMRR_LA_INVALID; + gmm_data->sync.mm_cell_info.status = MMGMM_LIMITED_SERVICE; + gmm_data->sync.mm_cell_info.gprs_indicator=MMGMM_GPRS_SUPP_NO; + break; + case NREG_LIMITED_SERVICE: + gmm_data->sync.mm_cell_info.status = MMGMM_LIMITED_SERVICE; + /* TCS 2.1 */ + /* TCS 2.1 */ + break; + default: + break; + } + /* + * SIGNAL CELL INFO + */ + sync_send_cell_info(); + /* + * SIGNAL NREG IND + */ + sig_sync_kern_mmgmm_nreg_ind(mmgmm_nreg_ind); + break; + + case SYNC_IDLE: + /* + * safe information: no or limited service + */ + switch (mmgmm_nreg_ind->service) /* TCS 2.1 */ + { + case NREG_NO_SERVICE: /* TCS 2.1 */ + gmm_data->sync.mm_cell_info.lac = GMMRR_LA_INVALID; + gmm_data->sync.mm_cell_info.status = MMGMM_LIMITED_SERVICE; + gmm_data->sync.mm_cell_info.gprs_indicator=MMGMM_GPRS_SUPP_NO; + break; + case NREG_LIMITED_SERVICE: + gmm_data->sync.mm_cell_info.status = MMGMM_LIMITED_SERVICE; + /* TCS 2.1 */ + /* TCS 2.1 */ + break; + default: + break; + } + /* + * synchronize + */ + if (sync_is_cid_equal()) + { + /* + * signal cell info + */ + sync_send_cell_info(); + } + else + { + /* + * synchronize with CELL IND + */ + SET_STATE ( SYNC, SYNC_WAIT_FOR_GPRS ); + /* + * Timer Supervision + */ + TRACE_EVENT ( "Info: START: TSYNC" ); + vsi_t_start ( GMM_handle , sync_TSYNC, TSYNC ); + } + /* + * handle nreg ind + */ + sig_sync_kern_mmgmm_nreg_ind(mmgmm_nreg_ind); + + break; + + case SYNC_WAIT_FOR_GPRS: + + TRACE_EVENT ( "Info: STOP: TSYNC" ); + vsi_t_stop ( GMM_handle , sync_TSYNC); + + SET_STATE ( SYNC, SYNC_IDLE); + + switch (mmgmm_nreg_ind->service) /* TCS 2.1 */ + { + case NREG_NO_SERVICE: /* TCS 2.1 */ + gmm_data->sync.mm_cell_info.lac = GMMRR_LA_INVALID; + gmm_data->sync.mm_cell_info.status = MMGMM_LIMITED_SERVICE; + gmm_data->sync.mm_cell_info.gprs_indicator=MMGMM_GPRS_SUPP_NO; + break; + case NREG_LIMITED_SERVICE: + gmm_data->sync.mm_cell_info.status = MMGMM_LIMITED_SERVICE; + /* TCS 2.1 */ + /* TCS 2.1 */ + break; + default: + break; + } + + sig_sync_kern_mmgmm_nreg_ind(mmgmm_nreg_ind); + break; + default: + TRACE_ERROR ("MMGMM_NREG_IND unexpected"); + PFREE(mmgmm_nreg_ind); + break; + } + GMM_RETURN; +} /* sync_mmgmm_nreg_ind */ +/* ++------------------------------------------------------------------------------ +| Function : sync_mmgmm_reg_rej ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_REG_REJ +| +| Parameters : *mmgmm_nreg_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sync_mmgmm_reg_rej (T_MMGMM_REG_REJ *mmgmm_reg_rej) +{ + GMM_TRACE_FUNCTION( "sync_mmgmm_reg_rej" ); + + switch( GET_STATE( SYNC ) ) + { + case SYNC_IDLE: + case SYNC_WAIT_FOR_GSM: + case SYNC_WAIT_FOR_GPRS: + gmm_data->sync.mm_cell_info.status = MMGMM_LIMITED_SERVICE; + switch (mmgmm_reg_rej->service) /* TCS 2.1 */ + { + case NREG_NO_SERVICE: /* TCS 2.1 */ + gmm_data->sync.mm_cell_info.lac = GMMRR_LA_INVALID; + break; + case NREG_LIMITED_SERVICE: + /* TCS 2.1 */ + break; + default: + break; + } + sig_sync_kern_mmgmm_reg_rej(mmgmm_reg_rej); + break; + default: + TRACE_ERROR ("MMGMM_REG_REJ unexpected"); + break; + } + GMM_RETURN; +} /* sync_mmgmm_reg_rej */ + +/* ++------------------------------------------------------------------------------ +| Function : sync_mmgmm_reg_cnf ++------------------------------------------------------------------------------ +| Description : Handles the primitive MMGMM_REG_CNF +| +| Parameters : *mmgmm_reg_cnf - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sync_mmgmm_reg_cnf (T_MMGMM_REG_CNF *mmgmm_reg_cnf) +{ + GMM_TRACE_FUNCTION( "sync_mmgmm_reg_cnf" ); + + switch( GET_STATE( SYNC ) ) + { + + case SYNC_IDLE: + case SYNC_WAIT_FOR_GSM: + case SYNC_WAIT_FOR_GPRS: + + /* Changes for Boot Time Speedup. GMM will get MMGMM_REG_CNF with + * bootup_cause = PWR_SCAN_START. + * No need to process this as it is response to dummy request. + * GMM need to send GMMREG_ATTACH_CNF indicating PWR_SCAN_START + */ + if (mmgmm_reg_cnf->bootup_cause EQ PWR_SCAN_START) + { + PALLOC ( gmmreg_attach_cnf, GMMREG_ATTACH_CNF ); + gmmreg_attach_cnf->attach_type = VAL_ATTACH_TYPE___DEF; + gmmreg_attach_cnf->plmn = mmgmm_reg_cnf->plmn; + gmmreg_attach_cnf->search_running = SEARCH_RUNNING; + gmmreg_attach_cnf->lac = mmgmm_reg_cnf->lac; + gmmreg_attach_cnf->rac = gmm_data->kern.sig_cell_info.env.rai.rac; + gmmreg_attach_cnf->cid = mmgmm_reg_cnf->cid; // #HM# + gmmreg_attach_cnf->gprs_indicator = gmm_data->kern.sig_cell_info.gmm_status; + gmmreg_attach_cnf->bootup_cause = PWR_SCAN_START; +#ifdef GMM_TCS4 + gmmreg_attach_cnf->rt = gmm_data->kern.sig_cell_info.rt; // TCS 4.0 +#endif + PSEND ( hCommMMI, gmmreg_attach_cnf ); + return; + } + gmm_data->sync.mm_cell_info.status = MMGMM_FULL_SERVICE; + sig_sync_kern_mmgmm_reg_cnf(mmgmm_reg_cnf); + break; + + default: + TRACE_ERROR ("MMGMM_REG_CNF unexpected"); + break; + } + GMM_RETURN; +} /* sync_mmgmm_nreg_ind */ +