FreeCalypso > hg > fc-magnetite
diff src/g23m-gprs/gmm/gmm_pei.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_pei.c Thu Oct 13 04:24:13 2016 +0000 @@ -0,0 +1,1588 @@ +/* ++----------------------------------------------------------------------------- +| Project : GPRS (8441) +| Modul : gmm_pei.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 module implements the process body interface +| for the entity GPRS Mobility Management (GMM) +| +| Exported functions: +| +| pei_create - Create the Protocol Stack Entity +| pei_init - Initialize Protocol Stack Entity +| pei_primitive - Process Primitive +| pei_timeout - Process Timeout +| pei_exit - Close resources and terminate +| pei_run - Process Primitive +| pei_config - Dynamic Configuration +| pei_monitor - Monitoring of physical Parameters ++----------------------------------------------------------------------------- +*/ + + +#define GMM_PEI_C + +#define ENTITY_GMM + +/*==== INCLUDES =============================================================*/ + +#include <stddef.h> /* to get definition of offsetof(), for MAK_FUNC_S */ +#include <stdlib.h> /* to get atoi for tokenizer in pei_init */ +#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 "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 "pei.h" /* to get PEI interface */ +#include "gmm.h" /* to get the global entity definitions */ +#include "gmm_f.h" /* to get the debug print function */ + +#include "gmm_kernp.h" /* to get primitive interface to KERN */ +#include "gmm_txp.h" /* to get primitive interface to TX */ +#include "gmm_rxp.h" /* to get primitive interface to RX */ +#include "gmm_rdyp.h" /* to get primitive interface to RDY */ +#include "gmm_syncp.h" /* to get primitive interface to SYNC */ + +#include "gmm_kernf.h" /* to get functions from KERN */ +#include "gmm_txf.h" /* to get functions from TX */ +#include "gmm_rxf.h" /* to get functions from RX */ +#include "gmm_rdyf.h" /* to get functions from RDY */ +#include "gmm_syncf.h" /* to get functions from SYNC */ + + +#include "ccdapi.h" /* to get ccd stuff */ +#include "tok.h" /* to get tokenizer */ +#include <string.h> /* to get memcpy */ + +#include "gmm_em.h" /*to get definitions of the Engineering Mode*/ +/*==== DEFINITIONS ==========================================================*/ + +/*==== TYPES ================================================================*/ + +/*==== GLOBAL VARS ==========================================================*/ + +/*==== LOCAL VARS ===========================================================*/ + +static BOOL first_access = TRUE; +static T_MONITOR gmm_mon; + +/* + * Jumptables to primitive handler functions. One table per SAP. + * + * Use MAK_FUNC_0 for primitives which contains no SDU. + * Use MAK_FUNC_S for primitives which contains a SDU. + */ + +/******************************************************* + * SAVE prim + *******************************************************/ + +#define PEI_SIGNAL_NOT_SAVED FALSE +#define PEI_SIGNAL_SAVED TRUE +#define PEI_END_SAVETAB 0xFF + +#define GMM_MAX_SIGNALS_SAVED 5 /* value adjusted to GMM requirements */ + +typedef struct SAVE_QUEUE +{ + void* prim; + T_VOID_FUNC func; + struct SAVE_QUEUE* next; +} T_SAVE_QUEUE; + +void gmm_pei_delete_queue( T_SAVE_QUEUE** queue ); + +typedef struct +{ + USHORT state; + USHORT signal[GMM_MAX_SIGNALS_SAVED]; +} T_SAVE_TAB; + +/*==== LOCAL PROTOTYPES =====================================================*/ +LOCAL void gmm_pei_handle_prim( T_VOID_FUNC func, void* prim ); +LOCAL BOOL gmm_pei_handle_save( void* prim, T_SAVE_QUEUE** queue, + const T_SAVE_TAB* table, T_VOID_FUNC func); +LOCAL void gmm_pei_handle_queue( T_SAVE_QUEUE** queue, + const T_SAVE_TAB* table); + +/*==== VAR LOCAL ============================================================*/ + +LOCAL T_SAVE_QUEUE* save_queue; /* SAVE queue hangers */ + +LOCAL const T_SAVE_TAB save_tab[] = { + + { KERN_GMM_REG_INITIATED, + {MMGMM_LUP_NEEDED_IND, + GMMREG_NET_REQ, + GMMREG_PLMN_RES, + 0, 0 } + }, + + { KERN_GMM_RAU_INITIATED, + {MMGMM_LUP_NEEDED_IND, + GMMREG_DETACH_REQ, + GMMREG_NET_REQ, + GMMREG_PLMN_RES, + 0 } + }, + + {KERN_GMM_RAU_WAIT_FOR_NPDU_LIST , + {GMMRR_CELL_IND, + 0, 0, 0, 0 } + }, + { KERN_GMM_DEREG_SUSPENDING, + {GMMREG_NET_REQ, + GMMREG_PLMN_RES, + GMMRR_CS_PAGE_IND, + MMGMM_CM_ESTABLISH_IND, + MMGMM_CM_EMERGENCY_IND } + }, + { KERN_GMM_REG_SUSPENDING, + {GMMREG_NET_REQ, + GMMREG_PLMN_RES, + GMMRR_CS_PAGE_IND, + MMGMM_CM_ESTABLISH_IND, + MMGMM_CM_EMERGENCY_IND } + }, + { KERN_GMM_REG_RESUMING, + {GMMREG_DETACH_REQ, + GMMRR_CS_PAGE_IND, + MMGMM_CM_ESTABLISH_IND, + MMGMM_CM_EMERGENCY_IND, + GMMREG_ATTACH_REQ } + }, + { KERN_GMM_DEREG_RESUMING, + {GMMREG_DETACH_REQ, + GMMRR_CS_PAGE_IND, + MMGMM_CM_ESTABLISH_IND, + MMGMM_CM_EMERGENCY_IND, + GMMREG_ATTACH_REQ} + }, + { PEI_END_SAVETAB, + { 0, 0, 0, 0, 0 } + } +}; +/******************************************************* + * End SAVE prim + *******************************************************/ + + +/* + * Function is needed for grr_table[]. This declaration can be removed + * as soon as this function is no more called (i.e. all primitives are + * handled). + */ +LOCAL void primitive_not_supported (void *data); + +static const T_FUNC gmmreg_table[] = +{ + MAK_FUNC_0(kern_gmmreg_attach_req, GMMREG_ATTACH_REQ), + MAK_FUNC_0(kern_gmmreg_detach_req, GMMREG_DETACH_REQ), + MAK_FUNC_0(kern_gmmreg_net_req, GMMREG_NET_REQ), + MAK_FUNC_0(kern_gmmreg_plmn_res, GMMREG_PLMN_RES), + MAK_FUNC_0(kern_gmmreg_plmn_mode_req, GMMREG_PLMN_MODE_REQ), + MAK_FUNC_0(kern_gmmreg_config_req, GMMREG_CONFIG_REQ), +}; + +#ifdef FF_EM_MODE +static const T_FUNC em_ul_table[] = +{ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x00 */ + /*EM_SC_GPRS_INFO_REQ cannot be sent directly from ACI to GRR, because no SAP is defined. + So it have to be passed via GMM.*/ + MAK_FUNC_0(em_gmm_sc_gprs_info_req, EM_SC_GPRS_INFO_REQ ), /* 0x01 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x02 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x03 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x04 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x05 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x06 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x07 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x08 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x09 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0A */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0B */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0C */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0D */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0E */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0F */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x10 */ + MAK_FUNC_0(em_gmm_pco_trace_req , EM_PCO_TRACE_REQ ), /* 0x11*/ /*PCO output*/ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x12 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x13 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x14 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x15 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x16 */ + MAK_FUNC_0(em_gmm_info_req, EM_GMM_INFO_REQ ), /* 0x17 */ + /*EM_GRLC_INFO_REQ cannot be sent directly from ACI to GRLC, so it is passed via GMM*/ + MAK_FUNC_0(em_gmm_grlc_info_req, EM_GRLC_INFO_REQ ), /* 0x18 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x19 */ + MAK_FUNC_0(em_gmm_grr_event_req, EM_GRR_EVENT_REQ ), /* 0x1A */ + MAK_FUNC_0(em_gmm_event_req, EM_GMM_EVENT_REQ ), /* 0x1B */ + MAK_FUNC_0(em_gmm_grlc_event_req, EM_GRLC_EVENT_REQ ), /* 0x1C */ + MAK_FUNC_0(em_gmm_throughput_info_req, EM_THROUGHPUT_INFO_REQ ) /* 0x1D */ +}; + +static const T_FUNC em_dl_table[] = +{ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x00 */ +/*EM_SC_GPRS_INFO_CNF cannot be sent directly from GRR to ACI, so it is passed via GMM*/ + MAK_FUNC_0(em_gmm_sc_gprs_info_cnf, EM_SC_GPRS_INFO_CNF ), /* 0x01 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x02 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x03 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x04 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x05 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x06 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x07 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x08 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x09 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0A */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0B */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0C */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0D */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0E */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0F */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x10 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x11 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x12 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x13 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x14 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x15 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x16 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x17 */ +/*EM_GRLC_INFO_CNF cannot be sent directly from ACI to GRLC, so it is passed via GMM*/ + MAK_FUNC_0(em_gmm_grlc_info_cnf, EM_GRLC_INFO_CNF ), /* 0x18 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x19 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x1A */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x1B */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x1C */ + MAK_FUNC_0(em_gmm_throughput_info_cnf, EM_THROUGHPUT_INFO_CNF ) /* 0x1D */ +}; +#endif /* FF_EM_MODE */ + + +static const T_FUNC gmmrr_table[] = +{ + MAK_FUNC_0(sync_gmmrr_cell_ind, GMMRR_CELL_IND), + MAK_FUNC_N(primitive_not_supported, 0 ), + MAK_FUNC_0(kern_gmmrr_page_ind, GMMRR_PAGE_IND), + MAK_FUNC_0(kern_gmmrr_cs_page_ind, GMMRR_CS_PAGE_IND), + MAK_FUNC_0(kern_gmmrr_suspend_cnf, GMMRR_SUSPEND_CNF), + MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */ + MAK_FUNC_N(primitive_not_supported, 0 ),/* TCS 2.1 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */ + MAK_FUNC_0(kern_gmmrr_cr_ind, GMMRR_CR_IND), +}; + + +static const T_FUNC cgrlc_table[] = /* TCS 2.1 */ +{ /* TCS 2.1 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */ + MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */ + MAK_FUNC_0(kern_cgrlc_status_ind, CGRLC_STATUS_IND ), /* TCS 2.1 */ + MAK_FUNC_0(kern_cgrlc_test_mode_cnf, CGRLC_TEST_MODE_CNF ), /* TCS 2.1 */ + MAK_FUNC_0(rdy_cgrlc_trigger_ind, CGRLC_TRIGGER_IND ), /* TCS 2.1 */ + MAK_FUNC_0(rdy_cgrlc_standby_state_ind, CGRLC_STANDBY_STATE_IND ), /* TCS 2.1 */ + MAK_FUNC_0(rdy_cgrlc_ready_state_ind, CGRLC_READY_STATE_IND ), /* TCS 2.1 */ +}; /* TCS 2.1 */ + + +#ifndef GMM_TCS4 +static const T_FUNC gmmsm_table[] = +{ + MAK_FUNC_0(kern_gmmsm_establish_req, GMMSM_ESTABLISH_REQ), + MAK_FUNC_S(tx_gmmsm_unitdata_req, GMMSM_UNITDATA_REQ), + MAK_FUNC_0(kern_gmmsm_sequence_res, GMMSM_SEQUENCE_RES), +}; +#else +static const T_FUNC mmpm_table[] = +{ +#ifdef REL99 + MAK_FUNC_0(kern_gmmsm_pdp_status_req, MMPM_PDP_CONTEXT_STATUS_REQ), +#else + MAK_FUNC_0(primitive_not_supported, MMPM_PDP_CONTEXT_STATUS_REQ), +#endif + MAK_FUNC_N(primitive_not_supported, 0), + MAK_FUNC_N(primitive_not_supported, 0), + MAK_FUNC_0(kern_gmmsm_sequence_res, MMPM_SEQUENCE_RES), + MAK_FUNC_S(tx_gmmsm_unitdata_req, MMPM_UNITDATA_REQ), +}; + +#endif /* #ifndef GMM_TCS4 */ + +static const T_FUNC gmmsms_table[] = +{ + MAK_FUNC_0(kern_gmmsms_reg_state_req, GMMSMS_REG_STATE_REQ) +}; + +LOCAL const T_FUNC sim_table[] = { + MAK_FUNC_0 (primitive_not_supported , SIM_READ_CNF ), /* 0x00 */ + MAK_FUNC_0 (primitive_not_supported , SIM_UPDATE_CNF ), + MAK_FUNC_0 (primitive_not_supported , SIM_READ_RECORD_CNF ), + MAK_FUNC_N (primitive_not_supported , 0 ), + MAK_FUNC_0 (primitive_not_supported , SIM_UPDATE_RECORD_CNF ), + MAK_FUNC_N (primitive_not_supported , 0 ), + MAK_FUNC_N (primitive_not_supported , 0 ), + MAK_FUNC_N (primitive_not_supported , 0 ), + MAK_FUNC_0 (primitive_not_supported , SIM_INCREMENT_CNF ), + MAK_FUNC_0 (primitive_not_supported , SIM_VERIFY_PIN_CNF ), + MAK_FUNC_0 (primitive_not_supported , SIM_CHANGE_PIN_CNF ), + MAK_FUNC_0 (primitive_not_supported , SIM_DISABLE_PIN_CNF ), + MAK_FUNC_0 (primitive_not_supported , SIM_ENABLE_PIN_CNF ), + MAK_FUNC_0 (primitive_not_supported , SIM_UNBLOCK_CNF ), + MAK_FUNC_0 (kern_sim_authentication_cnf , SIM_AUTHENTICATION_CNF ), + MAK_FUNC_0 (primitive_not_supported , SIM_MMI_INSERT_IND ), + MAK_FUNC_0 (primitive_not_supported , SIM_MM_INSERT_IND ), + MAK_FUNC_0 (kern_sim_remove_ind , SIM_REMOVE_IND ), + MAK_FUNC_0 (primitive_not_supported , SIM_SYNC_CNF ), + MAK_FUNC_0 (primitive_not_supported , SIM_ACTIVATE_CNF ), + MAK_FUNC_0 (primitive_not_supported , SIM_SMS_INSERT_IND ), /* 0x14 */ + MAK_FUNC_0 (primitive_not_supported , SIM_TOOLKIT_IND ), /* 0x15 */ + MAK_FUNC_0 (primitive_not_supported , SIM_TOOLKIT_CNF ), /* 0x16 */ + MAK_FUNC_0 (primitive_not_supported , SIM_ACTIVATE_IND ), /* 0x17 */ + MAK_FUNC_0 (primitive_not_supported , SIM_MM_INFO_IND ), /* 0x18 GMM GlumPs*/ + MAK_FUNC_0 (primitive_not_supported , SIM_ACCESS_CNF ), /* 0x19 */ + MAK_FUNC_0 (primitive_not_supported , SIM_FILE_UPDATE_IND ), /* 0x1a */ + MAK_FUNC_0 (kern_sim_gmm_insert_ind , SIM_GMM_INSERT_IND ), /* 0x1b */ +}; + +static const T_FUNC ll_table[] = +{ + MAK_FUNC_0(primitive_not_supported, LL_RESET_IND), + MAK_FUNC_S(primitive_not_supported, LL_ESTABLISH_CNF), + MAK_FUNC_S(primitive_not_supported, LL_ESTABLISH_IND), + MAK_FUNC_0(primitive_not_supported, LL_RELEASE_CNF), + MAK_FUNC_0(primitive_not_supported, LL_RELEASE_IND), + MAK_FUNC_S(primitive_not_supported, LL_XID_CNF), + MAK_FUNC_S(primitive_not_supported, LL_XID_IND), + MAK_FUNC_0(primitive_not_supported, LL_READY_IND), + MAK_FUNC_0(primitive_not_supported, LL_UNITREADY_IND), + MAK_FUNC_0(primitive_not_supported, LL_DATA_CNF), + MAK_FUNC_S(primitive_not_supported, LL_DATA_IND), + MAK_FUNC_S(rx_ll_unitdata_ind, LL_UNITDATA_IND) +}; + +static const T_FUNC llgmm_table[] = +{ + MAK_FUNC_0(kern_llgmm_status_ind, LLGMM_STATUS_IND), + MAK_FUNC_0(kern_llgmm_tlli_ind, LLGMM_TLLI_IND) +}; + +static const T_FUNC mmgmm_table[] = +{ + MAK_FUNC_0(sync_mmgmm_reg_cnf, MMGMM_REG_CNF), + MAK_FUNC_0(sync_mmgmm_reg_rej, MMGMM_REG_REJ), + MAK_FUNC_0(sync_mmgmm_nreg_ind, MMGMM_NREG_IND), + MAK_FUNC_0(kern_mmgmm_nreg_cnf, MMGMM_NREG_CNF), + MAK_FUNC_0(kern_mmgmm_plmn_ind, MMGMM_PLMN_IND), + MAK_FUNC_0(kern_mmgmm_auth_rej_ind, MMGMM_AUTH_REJ_IND), + MAK_FUNC_0(kern_mmgmm_cm_establish_ind, MMGMM_CM_ESTABLISH_IND), + MAK_FUNC_0(kern_mmgmm_cm_release_ind, MMGMM_CM_RELEASE_IND), + MAK_FUNC_0(sync_mmgmm_activate_ind, MMGMM_ACTIVATE_IND), + MAK_FUNC_0(kern_mmgmm_t3212_val_ind, MMGMM_T3212_VAL_IND), + MAK_FUNC_0(kern_mmgmm_info_ind, MMGMM_INFO_IND), + MAK_FUNC_0(kern_mmgmm_cm_emergency_ind, MMGMM_CM_EMERGENCY_IND), + MAK_FUNC_0(kern_mmgmm_lup_accept_ind, MMGMM_LUP_ACCEPT_IND), + MAK_FUNC_0(kern_mmgmm_lup_needed_ind, MMGMM_LUP_NEEDED_IND), + MAK_FUNC_0(kern_mmgmm_ciphering_ind, MMGMM_CIPHERING_IND), + MAK_FUNC_0(kern_mmgmm_tmsi_ind, MMGMM_TMSI_IND), + MAK_FUNC_0(kern_mmgmm_ahplmn_ind, MMGMM_AHPLMN_IND) +}; + + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +/* ++------------------------------------------------------------------------------ +| Function : primitive_not_supported ++------------------------------------------------------------------------------ +| Description : This function handles unsupported primitives. +| +| Parameters : - +| +| Return : - +| ++------------------------------------------------------------------------------ +*/ +LOCAL void primitive_not_supported (void *data) +{ + TRACE_FUNCTION ("primitive_not_supported"); + + PFREE (data); +} + + +/*==== PUBLIC FUNCTIONS =====================================================*/ + +/* ++------------------------------------------------------------------------------ +| Function : pei_primitive ++------------------------------------------------------------------------------ +| Description : This function is called by the frame when a primitive is +| received and needs to be processed. +| +| | +| GMMREG +| | | | | +| GMMSM | GMMSM GMMAA UPLINK +| | | | | +| +---v-----v-----v-----v----+ +| | | +| MMGMM ----> GMM | +| | | +| +---^--------^--------^----+ +| | | | +| | | LLGMM DOWNLINK +| | GMMRR | +| | | +| SIM +| | +| +| +| Parameters : prim - Pointer to the received primitive +| +| Return : PEI_OK - function succeeded +| PEI_ERROR - function failed +| ++------------------------------------------------------------------------------ +*/ +LOCAL SHORT pei_primitive (void * primptr) +{ + TRACE_FUNCTION ("pei_primitive"); +#ifdef TRACE_FUNC +#ifdef IDENTATION + gmm_data->deep=0; +#endif +#endif + + if (primptr NEQ NULL) + { + T_PRIM *prim = (T_PRIM *)primptr; + ULONG opc = prim->custom.opc; + USHORT n; + const T_FUNC *table; + + /* + * This must be called for Partition Pool supervision. Will be replaced + * by another macro some time. + */ + VSI_PPM_REC (&prim->custom, __FILE__, __LINE__); + + GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_STATE); + PTRACE_IN (opc); + + switch (SAP_NR(opc)) + { + case GMMREG_UL: + table = gmmreg_table; + n = TAB_SIZE (gmmreg_table); + break; + case GMMRR_DL: + table = gmmrr_table; + n = TAB_SIZE (gmmrr_table); + break; + case SAP_NR(CGRLC_DL): /* TCS 2.1 */ + table = cgrlc_table; /* TCS 2.1 */ + n = TAB_SIZE (cgrlc_table); /* TCS 2.1 */ + break; /* TCS 2.1 */ +#ifndef GMM_TCS4 + case GMMSM_UL: + table = gmmsm_table; + n = TAB_SIZE (gmmsm_table); + break; +#else + case SAP_NR(MMPM_UL): + table = mmpm_table; + n = TAB_SIZE (mmpm_table); + break; +#endif + case GMMSMS_UL: + table = gmmsms_table; + n = TAB_SIZE (gmmsms_table); + break; + case SAP_NR(SIM_UL):/*lint !e778 (Info -- Constant expression evaluates to 0 in operation '&') */ + table = sim_table; + n = TAB_SIZE (sim_table); + break; + case LL_DL: + table = ll_table; + n = TAB_SIZE (ll_table); + break; + case LLGMM_DL: + table = llgmm_table; + n = TAB_SIZE (llgmm_table); + break; + case MMGMM_DL: + table = mmgmm_table; + n = TAB_SIZE (mmgmm_table); + break; +#ifdef FF_EM_MODE + case EM_Ul: + table = em_ul_table; + n = TAB_SIZE (em_ul_table); + break; + case EM_Dl: + table = em_dl_table; + n = TAB_SIZE (em_dl_table); + break; +#endif /* FF_EM_MODE */ + default: + TRACE_ERROR("pei_primitive. Unknown SAP"); + table = NULL; + n = 0; + break; + } + + if (table != NULL) + { + if (PRIM_NR(opc) < n) + { + table += PRIM_NR(opc); +#ifdef PALLOC_TRANSITION + P_SDU(prim) = table->soff ? (T_sdu*) (((char*)&prim->data) + table->soff) : 0; +#ifndef NO_COPY_ROUTING + P_LEN(prim) = table->size + sizeof (T_PRIM_HEADER); +#endif /* NO_COPY_ROUTING */ +#endif /* PALLOC_TRANSITION */ + + /******************************************************* + * SAVE prim + *******************************************************/ + + if( gmm_pei_handle_save( prim, &save_queue, save_tab, table->func ) + == PEI_SIGNAL_NOT_SAVED ) + { + UBYTE old_kern_state = gmm_data->kern.state; + /******************************************************* + * SAVE prim + *******************************************************/ + + JUMP (table->func) (P2D(prim)); + + /******************************************************* + * SAVE prim + *******************************************************/ + if( gmm_data->kern.state != old_kern_state ) + { + gmm_pei_handle_queue(&save_queue, save_tab); + } + } + else + { + TRACE_2_INFO ("S:%2d SAVE of Primitive 0x%x", gmm_data->kern.state, opc ); + } + + + + /******************************************************* + * End SAVE prim + *******************************************************/ + + } + else + { + primitive_not_supported (P2D(prim)); + } + return PEI_OK; + } + + /* + * primitive is not a GSM primitive - forward it to the environment + */ + if (opc & SYS_MASK) + vsi_c_primitive (VSI_CALLER prim); + else + { + PFREE (P2D(prim)); + return PEI_ERROR; + } + } + return PEI_OK; +} + + +/* ++------------------------------------------------------------------------------ +| Function : pei_init ++------------------------------------------------------------------------------ +| Description : This function is called by the frame. It is used to initialise +| the entitiy. +| +| Parameters : handle - task handle +| +| Return : PEI_OK - entity initialised +| PEI_ERROR - entity not (yet) initialised +| ++------------------------------------------------------------------------------ +*/ +LOCAL SHORT pei_init (T_HANDLE handle) +{ + TRACE_FUNCTION ("pei_init"); + + /* + * Initialize task handle + */ + GMM_handle = handle; + + /* + * Open communication channels + */ + if (hCommSMS < VSI_OK) + { + if ((hCommSMS = vsi_c_open (VSI_CALLER SMS_NAME)) < VSI_OK) + return PEI_ERROR; + } + if (hCommSM < VSI_OK) + { + if ((hCommSM = vsi_c_open (VSI_CALLER SM_NAME)) < VSI_OK) + return PEI_ERROR; + } + if (hCommGRLC < VSI_OK) /* TCS 2.1 */ + { /* TCS 2.1 */ + if ((hCommGRLC = vsi_c_open (VSI_CALLER GRLC_NAME)) < VSI_OK) /* TCS 2.1 */ + return PEI_ERROR; /* TCS 2.1 */ + } /* TCS 2.1 */ + + if (hCommGRR < VSI_OK) + { + if ((hCommGRR = vsi_c_open (VSI_CALLER GRR_NAME)) < VSI_OK) + return PEI_ERROR; + } + if (hCommLLC < VSI_OK) + { + if ((hCommLLC = vsi_c_open (VSI_CALLER LLC_NAME)) < VSI_OK) + return PEI_ERROR; + } + if (hCommSIM < VSI_OK) + { + if ((hCommSIM = vsi_c_open (VSI_CALLER SIM_NAME)) < VSI_OK) + return PEI_ERROR; + } + if (hCommMM < VSI_OK) + { + if ((hCommMM = vsi_c_open (VSI_CALLER MM_NAME)) < VSI_OK) + return PEI_ERROR; + } + if (hCommMMI < VSI_OK) + { + if ((hCommMMI = vsi_c_open (VSI_CALLER ACI_NAME)) < VSI_OK) /* TCS 2.1 */ + return PEI_ERROR; + } + if (hCommGMM < VSI_OK) + { + if ((hCommGMM = vsi_c_open (VSI_CALLER GMM_NAME)) < VSI_OK) + return PEI_ERROR; + } +#ifdef GMM_TCS4 + if (hCommUPM < VSI_OK) + { + if ((hCommUPM = vsi_c_open (VSI_CALLER UPM_NAME)) < VSI_OK) + return PEI_ERROR; + } +#endif + + + /* + * Initialize global pointer llc_data. This is required to access all + * entity data. + */ + gmm_data = &gmm_data_base; + + /* + * Initialite ccd + */ + ccd_init (); + +#ifdef FF_EM_MODE + em_init_gmm_event_trace(); +#endif /* FF_EM_MODE */ + + + /* + * Initialize entity data (call init function of every service) + */ + + kern_init(); + rxgmm_init(); + txgmm_init(); + rdy_init(); + sync_gmm_init(); + + GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_FULL); + + return (PEI_OK); +} + +/* ++------------------------------------------------------------------------------ +| Function : pei_timeout ++------------------------------------------------------------------------------ +| Description : This function is called by the frame when a timer has expired. +| +| Parameters : index - timer index +| +| Return : PEI_OK - timeout processed +| PEI_ERROR - timeout not processed +| ++------------------------------------------------------------------------------ +*/ +LOCAL SHORT pei_timeout (USHORT index) +{ + UBYTE old_kern_state; + TRACE_FUNCTION ("pei_timeout"); + + old_kern_state = gmm_data->kern.state; + /* + * Process timeout + */ + switch (index) + { + case kern_T3302: + /* + * T3302 expired. + */ + kern_t3302 (); + break; + case kern_T3310: + /* + * T3310 expired. + */ + kern_t3310 (); + break; + case kern_T3311: + /* + * T3311 expired. + */ + kern_t3311 (); + break; + case kern_T3321: + /* + * T3321 expired. + */ + kern_t3321 (); + break; + case rdy_T3312: + /* + * T3312 expired. + */ + kern_t3312 (); + break; + case kern_TPOWER_OFF: + kern_tpower_off(); + break; + case kern_TLOCAL_DETACH: + kern_tlocal_detach(); + break; + case sync_TSYNC: + sync_tsync(); + break; + default: + TRACE_ERROR("Unknown Timeout"); + return PEI_ERROR; + } + + if( gmm_data->kern.state != old_kern_state ) + { + gmm_pei_handle_queue( &save_queue, save_tab); + } + return PEI_OK; +} + +/* ++------------------------------------------------------------------------------ +| Function : pei_signal ++------------------------------------------------------------------------------ +| Description : This function is called by the frame when a signal has been +| received. +| +| Parameters : opc - signal operation code +| *data - pointer to primitive +| +| Return : PEI_OK - signal processed +| PEI_ERROR - signal not processed +| ++------------------------------------------------------------------------------ +*/ +LOCAL SHORT pei_signal (ULONG opc, void *data) +{ + TRACE_FUNCTION ("pei_signal"); + + /* + * Process signal + */ + switch (opc) + { + default: + TRACE_ERROR("Unknown Signal OPC"); + break; + }/*lint !e764 (Info -- switch statement does not have a case) */ + + return PEI_OK; +} + +/* ++------------------------------------------------------------------------------ +| Function : pei_exit ++------------------------------------------------------------------------------ +| Description : This function is called by the frame when the entity is +| terminated. All open resources are freed. +| +| Parameters : - +| +| Return : PEI_OK - exit sucessful +| PEI_ERROR - exit not sueccessful +| ++------------------------------------------------------------------------------ +*/ +LOCAL SHORT pei_exit (void) +{ + TRACE_FUNCTION ("pei_exit"); + + /* + * Close communication channels + */ + vsi_c_close (VSI_CALLER hCommSMS); + hCommSMS = VSI_ERROR; + + vsi_c_close (VSI_CALLER hCommSM); + hCommSM = VSI_ERROR; + + vsi_c_close (VSI_CALLER hCommGRLC); /* TCS 2.1 */ + hCommGRLC = VSI_ERROR; /* TCS 2.1 */ + + vsi_c_close (VSI_CALLER hCommGRR); + hCommGRR = VSI_ERROR; + + vsi_c_close (VSI_CALLER hCommLLC); + hCommLLC = VSI_ERROR; + + vsi_c_close (VSI_CALLER hCommSIM); + hCommSIM = VSI_ERROR; + + vsi_c_close (VSI_CALLER hCommMM); + hCommMM = VSI_ERROR; + + vsi_c_close (VSI_CALLER hCommMMI); + hCommMMI = VSI_ERROR; + + vsi_c_close (VSI_CALLER hCommGMM); + hCommGMM = VSI_ERROR; + + /* + * delete queues + */ + gmm_pei_delete_queue(&save_queue); + + /* + * close ccd + */ + ccd_exit (); + + return PEI_OK; +} + +/* ++------------------------------------------------------------------------------ +| Function : pei_run ++------------------------------------------------------------------------------ +| Description : This function is called by the frame when entering the main +| loop. This fucntion is only required in the active variant. +| +| This function is not used. +| +| Parameters : handle - Communication handle +| +| Return : PEI_OK - sucessful +| PEI_ERROR - not successful +| ++------------------------------------------------------------------------------ +*/ +LOCAL SHORT pei_run (T_HANDLE TaskHandle, T_HANDLE ComHandle ) +{ + return PEI_OK; +} + + +/* ++------------------------------------------------------------------------------ +| Function : gmm_tok_key ++------------------------------------------------------------------------------ +| Description : This function is used by pei_config in windows test +| environment for string tokenizing for CHECK STATE command, e.g. +| COMMAND("GMM CONFIG CHECK_STATE=<REG_NORMAL_SERVICE>"); +| +| +| Parameters : +| +| Return : +| +| ++------------------------------------------------------------------------------ +*/ +#ifndef _TARGET_ +typedef struct KW_STATE_DATA +{ + char keyword[60]; + SHORT code; +} KW_STATE_DATA; + +LOCAL SHORT gmm_tok_key (KW_STATE_DATA * keytab, char * keyword) +{ + /* + * Empty string terminates + */ + while (keytab->keyword[0]) + { + if (strcmp (keytab->keyword, keyword ) == 0) + return (keytab->code); + keytab++; + } + + return (TOK_NOT_FOUND); +} +#endif + +/* ++------------------------------------------------------------------------------ +| Function : pei_config ++------------------------------------------------------------------------------ +| Description : This function is called by the frame when a primitive is +| received indicating dynamic configuration. +| +| This function is not used in this entity. +| +| Parameters : handle - Communication handle +| +| Return : PEI_OK - sucessful +| PEI_ERROR - not successful +| ++------------------------------------------------------------------------------ +*/ +LOCAL SHORT pei_config (char *inString) +{ + TRACE_FUNCTION ("pei_config"); + TRACE_FUNCTION (inString); + +#ifndef NCONFIG + /* + * Parse next keyword and number of variables + */ + if(!strcmp(inString,"PERIODIC_LAU")) + { + PALLOC (mmgmm_lup_needed_ind, MMGMM_LUP_NEEDED_IND); + mmgmm_lup_needed_ind->reason = MMGMM_T3212; /* TCS 2.1 */ + TRACE_EVENT( "Info: Periodic LAU requested by MM"); + PSEND (hCommGMM, mmgmm_lup_needed_ind); + } + else if(!strcmp(inString,"PERIODIC_RAU")) + { + kern_t3312(); + } + else if(!strcmp(inString,"REATTACH")) + { + PALLOC (gmmrr_page_ind, GMMRR_PAGE_IND); + gmmrr_page_ind->page_id=GMMRR_IMSI; + PSEND (hCommGMM, gmmrr_page_ind); + } + else if(!strcmp(inString,"CELL")) + { + PALLOC (gmmrr_cell_ind, GMMRR_CELL_IND); + gmmrr_cell_ind->cell_info.service_state=GMMRR_SERVICE_FULL; + gmmrr_cell_ind->cell_info.cell_env.rai.lac=0x2506; + gmmrr_cell_ind->cell_info.cell_env.rai.rac=0x71; + gmmrr_cell_ind->cell_info.net_mode=gmm_data->config.nmo; + PSEND (hCommGMM, gmmrr_cell_ind); + } + else if(!strcmp(inString,"NMO_I")) + { + gmm_data->config.nmo = GMMRR_NET_MODE_I; + } + else if(!strcmp(inString,"NMO_II")) + { + gmm_data->config.nmo = GMMRR_NET_MODE_II; + } + else if(!strcmp(inString,"NMO_III")) + { + gmm_data->config.nmo = GMMRR_NET_MODE_III; + } + else if(!strcmp(inString,"GMM_INFO")) + { + PALLOC (gmmreg_info_ind, GMMREG_INFO_IND); + PSEND (hCommMMI, gmmreg_info_ind); + } + + else if(!strcmp(inString,"RESET_SIM")) + { + gmm_data->sim_gprs_invalid = TRUE; + kern_sim_del_locigprs (); + kern_sim_gmm_update(); + kern_mm_auth_rej(); + { + PALLOC (sim_update_req, SIM_UPDATE_REQ); + + sim_update_req->source = SRC_GMM; + /* req_id is not filled since response is not handled */ + + sim_update_req->v_path_info = FALSE; + + sim_update_req->datafield = SIM_FPLMN; + sim_update_req->length = 12; + memset (sim_update_req->trans_data,0xff,12); + sim_update_req->offset = 0; + + PSEND (hCommSIM, sim_update_req); + } + { + PALLOC (sim_update_req, SIM_UPDATE_REQ); + + sim_update_req->source = SRC_GMM; + + /* req_id is not filled since response is not handled */ + sim_update_req->v_path_info = FALSE; + + sim_update_req->datafield = SIM_LOCI; + sim_update_req->length = 11; + memset (sim_update_req->trans_data,0xff,8); + sim_update_req->trans_data[8]=0xfe; + sim_update_req->trans_data[9]=0x0; + sim_update_req->trans_data[10]=GU2_NOT_UPDATED; + sim_update_req->offset = 0; + + PSEND (hCommSIM, sim_update_req); + } + } + else if(!strcmp(inString,"ANITE")) + { + gmm_data->anite = TRUE; + } + else if(!strcmp(inString,"CIPHER_OFF")) + { + gmm_data->config.cipher_on = 0x00; + TRACE_EVENT ("ciphering switched OFF"); + } + else if(!strcmp(inString,"CIPHER_ON")) + { + gmm_data->config.cipher_on |= 0x01; + } + else if(!strcmp(inString,"PREUSE_OFF")) + { + gmm_data->config.preuse_off = TRUE; + } + +#ifdef REL99 + else if(!strcmp(inString,"CL_SGSN_REL_98_OR_OLDER")) /* TCS 4.0 */ + { /* TCS 4.0 */ + /*gmm_data->config.sgsnr_flag = R_98NW; */ + cl_nwrl_set_sgsn_release(PS_SGSN_98_OLDER); /*CL function*/ /* TCS 4.0 */ + } /* TCS 4.0 */ + else if(!strcmp(inString,"CL_SGSN_REL_99_ONWARDS")) /* TCS 4.0 */ + { /* TCS 4.0 */ + /* gmm_data->config.sgsnr_flag = R_99NW; */ + cl_nwrl_set_sgsn_release(PS_SGSN_99_ONWARDS); /*CL function*/ /* TCS 4.0 */ + } /* TCS 4.0 */ + else if (!strcmp(inString,"CELL_NOTIFY_ON")) /* TCS 4.0 */ + { /* TCS 4.0 */ + gmm_data->config.cell_notification = FIRST_CELL_NOTIFY; /* TCS 4.0 */ + } /* TCS 4.0 */ + else if (!strcmp(inString, "CELL_NOTIFY_OFF")) /* TCS 4.0 */ + { /* TCS 4.0 */ + gmm_data->config.cell_notification = NO_CELL_NOTIFY; /* TCS 4.0 */ + } /* TCS 4.0 */ +#endif + +#ifdef _SIMULATION_ + else if(!strcmp(inString, "NEXT_TIMEOUT")) + { + T_TIME old_value = 0; + T_TIME new_value = 0; + USHORT timer; + USHORT timeout = TIMER_MAX; + + /* Find next timer to timeout */ + + for(timer = 0; timer < TIMER_MAX; timer++) + { + if ( VSI_OK == vsi_t_status ( GMM_handle ,timer, &new_value )) + { + if (new_value >0 ) + { + if((old_value==0)|| + (new_value < old_value)) + { + old_value = new_value; + timeout = timer; + } + } + } + } + + + /* Force timeout */ + if(TIMER_MAX != timeout ) + { + TRACE_1_INFO("gmm_pei_config - forcing timeout:%d", timeout); + + vsi_t_stop ( GMM_handle, timeout); + + for(timer = 0; timer < TIMER_MAX ; timer++) + { + if ( VSI_OK == vsi_t_status ( GMM_handle ,timer, &new_value )) + { + if (timer!=timeout ) + { + if (new_value>0 && new_value-old_value >0 ) + { + vsi_t_start ( GMM_handle , timer, new_value-old_value ); + } + } + } + } + + pei_timeout(timeout); + } + } +#endif + +#define GMM_CONFIG_DRX 1 +#define GMM_CONFIG_GEA 2 + +#ifndef _TARGET_ +#define GMM_CONFIG_CHECK_STATE 3 +#endif + +#define GMM_DRX "DRX" +#define GMM_GEA "GEA" + +#ifndef _TARGET_ +#define GMM_CHECK_STATE "CHECK_STATE" + +#define GMM_NULL_NO_IMSI "NULL_NO_IMSI" +#define GMM_NULL_IMSI "NULL_IMSI" +#define GMM_DEREG_INITIATED "DEREG_INITIATED" +#define GMM_DEREG_ATTEMPTING_TO_ATTACH "DEREG_ATTEMPTING_TO_ATTACH" +#define GMM_DEREG_NO_CELL_AVAILABLE "DEREG_NO_CELL_AVAILABLE" +#define GMM_DEREG_LIMITED_SERVICE "DEREG_LIMITED_SERVICE" +#define GMM_DEREG_NO_IMSI "DEREG_NO_IMSI" +#define GMM_DEREG_PLMN_SEARCH "DEREG_PLMN_SEARCH" +#define GMM_DEREG_SUSPENDED "DEREG_SUSPENDED" + +#define GMM_REG_INITIATED "REG_INITIATED" + +#define GMM_REG_NO_CELL_AVAILABLE "REG_NO_CELL_AVAILABLE" +#define GMM_REG_LIMITED_SERVICE "REG_LIMITED_SERVICE" +#define GMM_REG_ATTEMPTING_TO_UPDATE_MM "REG_ATTEMPTING_TO_UPDATE_MM " +#define GMM_REG_ATTEMPTING_TO_UPDATE "REG_ATTEMPTING_TO_UPDATE" +#define GMM_REG_RESUMING "REG_RESUMING" +#define GMM_REG_SUSPENDED "REG_SUSPENDED" +#define GMM_REG_NORMAL_SERVICE "REG_NORMAL_SERVICE" + +#define GMM_RAU_INITIATED "RAU_INITIATED" + +#define GMM_RAU_WAIT_FOR_NPDU_LIST "RAU_WAIT_FOR_NPDU_LIST" + +#define GMM_REG_IMSI_DETACH_INITIATED "REG_IMSI_DETACH_INITIATED" + +#define GMM_DEREG_SUSPENDING "DEREG_SUSPENDING" +#define GMM_DEREG_RESUMING "DEREG_RESUMING" + +#define GMM_REG_SUSPENDING "REG_SUSPENDING" +#define GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ "NULL_NO_IMSI_LIMITED_SERVICE_REQ" +#define GMM_NULL_IMSI_LIMITED_SERVICE_REQ "NULL_IMSI_LIMITED_SERVICE_REQ" +#define GMM_REG_TEST_MODE "REG_TEST_MODE" +#define GMM_NULL_PLMN_SEARCH "NULL_PLMN_SEARCH" +#define GMM_REG_TEST_MODE_NO_IMSI "REG_TEST_MODE_NO_IMSI " + +#endif + + { + LOCAL KW_DATA kwtab[] = + { + GMM_DRX, GMM_CONFIG_DRX, + GMM_GEA, GMM_CONFIG_GEA, +#ifndef _TARGET_ + GMM_CHECK_STATE, GMM_CONFIG_CHECK_STATE, +#endif + "", 0 + }; +#ifndef _TARGET_ + LOCAL KW_STATE_DATA kw_state_tab[] = + { + GMM_NULL_NO_IMSI ,KERN_GMM_NULL_NO_IMSI, + GMM_NULL_IMSI ,KERN_GMM_NULL_IMSI, + GMM_DEREG_INITIATED ,KERN_GMM_DEREG_INITIATED, + GMM_DEREG_ATTEMPTING_TO_ATTACH ,KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH, + GMM_DEREG_NO_CELL_AVAILABLE ,KERN_GMM_DEREG_NO_CELL_AVAILABLE, + GMM_DEREG_LIMITED_SERVICE ,KERN_GMM_DEREG_LIMITED_SERVICE, + GMM_DEREG_NO_IMSI ,KERN_GMM_DEREG_NO_IMSI, + GMM_DEREG_PLMN_SEARCH ,KERN_GMM_DEREG_PLMN_SEARCH, + GMM_DEREG_SUSPENDED ,KERN_GMM_DEREG_SUSPENDED, + + GMM_REG_INITIATED ,KERN_GMM_REG_INITIATED, + + GMM_REG_NO_CELL_AVAILABLE ,KERN_GMM_REG_NO_CELL_AVAILABLE, + GMM_REG_LIMITED_SERVICE ,KERN_GMM_REG_LIMITED_SERVICE, + GMM_REG_ATTEMPTING_TO_UPDATE_MM ,KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM , + GMM_REG_ATTEMPTING_TO_UPDATE ,KERN_GMM_REG_ATTEMPTING_TO_UPDATE, + GMM_REG_RESUMING ,KERN_GMM_REG_RESUMING, + GMM_REG_SUSPENDED ,KERN_GMM_REG_SUSPENDED, + GMM_REG_NORMAL_SERVICE ,KERN_GMM_REG_NORMAL_SERVICE, + + GMM_RAU_INITIATED ,KERN_GMM_RAU_INITIATED, + + GMM_RAU_WAIT_FOR_NPDU_LIST ,KERN_GMM_RAU_WAIT_FOR_NPDU_LIST, + + GMM_REG_IMSI_DETACH_INITIATED ,KERN_GMM_REG_IMSI_DETACH_INITIATED, + + GMM_DEREG_SUSPENDING ,KERN_GMM_DEREG_SUSPENDING, + GMM_DEREG_RESUMING ,KERN_GMM_DEREG_RESUMING, + GMM_REG_SUSPENDING ,KERN_GMM_REG_SUSPENDING, + + GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ ,KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ, + GMM_NULL_IMSI_LIMITED_SERVICE_REQ ,KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ, + GMM_REG_TEST_MODE ,KERN_GMM_REG_TEST_MODE, + GMM_NULL_PLMN_SEARCH ,KERN_GMM_NULL_PLMN_SEARCH, + GMM_REG_TEST_MODE_NO_IMSI ,KERN_GMM_REG_TEST_MODE_NO_IMSI , + "", 0 + }; + +#endif + SHORT valno; + char *keyw; + char *val[10]; + + tok_init (inString); + + while((valno = tok_next(&keyw,val)) NEQ TOK_EOCS) + { + switch ((tok_key((KW_DATA *)kwtab, keyw))) + { + case GMM_CONFIG_DRX: + if (3==valno) + { + TRACE_EVENT ("use of DRX <split_pg_cycle_code,split_on_ccch,non_drx_timer>"); + gmm_data->drx_parameter.split_pg_cycle_code = atoi (val[0]); + gmm_data->drx_parameter.split_on_ccch = atoi (val[1]); + gmm_data->drx_parameter.non_drx_timer = atoi (val[2]); + } + else + { + TRACE_ERROR("[PEI_CONFIG]: use CONFIG DRX <1,2,3>"); + } + break; + case GMM_CONFIG_GEA: + if (1==valno) + { + TRACE_EVENT ("GEA=<bit_field of wanted GEA in dec>"); + + gmm_data->config.cipher_on |= atoi (val[0]); + TRACE_1_INFO("GEA2=%d", (gmm_data->config.cipher_on & 0x02)>0); + TRACE_1_INFO("GEA3=%d", (gmm_data->config.cipher_on & 0x04)>0); + TRACE_1_INFO("GEA4=%d", (gmm_data->config.cipher_on & 0x08)>0); + TRACE_1_INFO("GEA5=%d", (gmm_data->config.cipher_on & 0x10)>0); + TRACE_1_INFO("GEA6=%d", (gmm_data->config.cipher_on & 0x20)>0); + TRACE_1_INFO("GEA7=%d", (gmm_data->config.cipher_on & 0x40)>0); + } + else + { + TRACE_ERROR("[PEI_CONFIG]: use CONFIG GEA=<0-255>//255 means all GEA wanted"); + } + break; +#ifndef _TARGET_ + case GMM_CONFIG_CHECK_STATE: + if(1==valno) + { + if (gmm_tok_key ((KW_STATE_DATA *)kw_state_tab, val[0])!=GET_STATE(KERN)) + { + PALLOC ( cgrlc_status_ind, CGRLC_STATUS_IND ); /* TCS 2.1 */ + PSEND ( hCommGMM, cgrlc_status_ind ); /* TCS 2.1 */ + TRACE_1_OUT_PARA( "neq %s", val[0]); + TRACE_ERROR("state wrong"); + } + else + { + TRACE_1_INFO("state %s ok",val[0]); + } + } + else + { + TRACE_ERROR("[PEI_CONFIG]: USE CONFIG CHECK_STATE <state>"); + } + break; +#endif + default: + break; + } + } + } +#endif + return PEI_OK; +} + +/* ++------------------------------------------------------------------------------ +| Function : pei_monitor ++------------------------------------------------------------------------------ +| Description : This function is called by the frame in case sudden entity +| specific data is requested (e.g. entity Version). +| +| Parameters : out_monitor - return the address of the data to be +| monitoredCommunication handle +| +| Return : PEI_OK - sucessful (address in out_monitor is valid) +| PEI_ERROR - not successful +| ++------------------------------------------------------------------------------ +*/ +LOCAL SHORT pei_monitor (void ** out_monitor) +{ + TRACE_FUNCTION ("pei_monitor"); + + /* + * Version = "0.S" (S = Step). + */ + gmm_mon.version = "GMM 0.1"; + *out_monitor = &gmm_mon; + + return PEI_OK; +} + +/* ++------------------------------------------------------------------------------ +| Function : pei_create ++------------------------------------------------------------------------------ +| Description : This function is called by the frame when the process is +| created. +| +| Parameters : out_name - Pointer to the buffer in which to locate +| the name of this entity +| +| Return : PEI_OK - entity created successfuly +| PEI_ERROR - entity could not be created +| ++------------------------------------------------------------------------------ +*/ +GLOBAL SHORT pei_create (T_PEI_INFO **info) +{ +static T_PEI_INFO pei_info = + { + "GMM", /* name */ + { /* pei-table */ + pei_init, + pei_exit, + pei_primitive, + pei_timeout, + pei_signal, + pei_run, + pei_config, + pei_monitor + }, + 2048, /* stack size */ + 25, /* queue entries */ + 190, /* priority (1->low, 255->high) */ + TIMER_MAX, /* number of timers */ + 0x03|PRIM_NO_SUSPEND /* flags: bit 0 active(0) body/passive(1) */ + }; /* bit 1 com by copy(0)/reference(1) */ + + + TRACE_FUNCTION ("pei_create"); + + /* + * Close Resources if open + */ + if (first_access) + first_access = FALSE; + else + pei_exit(); + + /* + * Export startup configuration data + */ + *info = &pei_info; + + return (PEI_OK); +} + +/* ++------------------------------------------------------------------------------ +| Function : gmm_pei_handle_queue ++------------------------------------------------------------------------------ +| Description : This function searches for the first stored primitive, which +| must not be saved further in current state. +| +| Parameters : state - current state of the instance +| queue - PtrPtr to the hanger of the instance save queue +| table - Ptr to the state/signals-to-save table +| inst_data - Ptr to instance data ++------------------------------------------------------------------------------ +*/ +LOCAL void gmm_pei_handle_queue( T_SAVE_QUEUE** queue, + const T_SAVE_TAB* table) +{ + /* search for a T_SAVE_TAB entry which fits to current state */ + if( *queue ) + while( table->state != PEI_END_SAVETAB && table->state != gmm_data->kern.state ) + table++; + + while( *queue ) + { + T_SAVE_QUEUE* current = *queue; + ULONG opc = ((T_PRIM_HEADER*)current->prim)->opc; + USHORT n = 0; + + if( table->state != PEI_END_SAVETAB ) + { + /* search for this signals in savelist of this state */ + while( n < GMM_MAX_SIGNALS_SAVED && table->signal[n] && + table->signal[n] != opc ) + n++; + } + + if( table->signal[n] != opc ) + { + TRACE_1_INFO ("Pimitive 0x%x send from SAVE queue", + ((T_PRIM_HEADER*)current->prim)->opc ); + /* this signal must not further be stored -> handle it now */ + /* first remove it from save queue, because of recursion!! */ + *queue = current->next; + gmm_pei_handle_prim(current->func, current->prim ); + /* and free memory after last use */ + MFREE( current ); + + /* recursion! handle at maximum one prim at once -> job done */ + return; + } + + /* goto next queued signal */ + queue = &((*queue)->next); + } +} +/* ++------------------------------------------------------------------------------ +| Function : gmm_pei_delete_queue ++------------------------------------------------------------------------------ +| Description : This function removes all stored primitives from the queue and +| frees the memory. +| +| Parameters : queue - PtrPtr to the hanger of the instance save queue ++------------------------------------------------------------------------------ +*/ +GLOBAL void gmm_pei_delete_queue( T_SAVE_QUEUE** queue ) +{ + while( *queue ) + { + T_SAVE_QUEUE* current = *queue; + + + TRACE_1_INFO( "Pimitive 0x%x deleted from SAVE queue", + ((T_PRIM_HEADER*)current->prim)->opc ); + + *queue = current->next; + PFREE( P2D(current->prim) ); + MFREE( current ); + } +} +/* ++------------------------------------------------------------------------------ +| Function : gmm_pei_handle_prim ++------------------------------------------------------------------------------ +| Description : This function calls the handle function of the signal +| +| Parameters : func - Function, which should handle the signal +| inst_data - Ptr to instance data +| *prim - Ptr to primitive ++------------------------------------------------------------------------------ +*/ +LOCAL void gmm_pei_handle_prim( T_VOID_FUNC func, void* prim ) +{ + JUMP(func)( P2D(prim)); + + gmm_pei_handle_queue( &save_queue, save_tab); +} +/* ++------------------------------------------------------------------------------ +| Function : gmm_pei_handle_save ++------------------------------------------------------------------------------ +| Description : This function saves the prim pointer to the save queue, if +| this is necessary in current state. +| +| Parameters : *prim - Ptr to primitive +| state - Current state of the instance +| queue - PtrPtr to the hanger of the instance save queue +| table - Ptr to the state/signals-to-save table +| func - Function, which should handle the signal +| +| Returns : PEI_SIGNAL_SAVED - if signal is stored to save queue +| PEI_SIGNAL_NOT_SAVED - else ++------------------------------------------------------------------------------ +*/ +LOCAL BOOL gmm_pei_handle_save( void* prim, T_SAVE_QUEUE** queue, + const T_SAVE_TAB* table, T_VOID_FUNC func ) +{ + ULONG opc = ((T_PRIM_HEADER*)prim)->opc; + + while( table->state != PEI_END_SAVETAB ) + { + if( table->state == gmm_data->kern.state ) + { + UBYTE n = 0; + + /* check for signals to save */ + while( n < GMM_MAX_SIGNALS_SAVED && table->signal[n] ) + { + if( table->signal[n] == opc ) + { + /* store signal to end of save queue */ + while( *queue ) + queue = &((*queue)->next); + + MALLOC( *queue, sizeof(T_SAVE_QUEUE) ); + + if( *queue ) + { + (*queue)->prim = prim; + (*queue)->func = func; + (*queue)->next = NULL; + } + else + { + TRACE_ERROR( "Out of memory in mm_pei_handle_save()" ); + return PEI_SIGNAL_NOT_SAVED; + } + + return PEI_SIGNAL_SAVED; + } + + /* goto next signal */ + n++; + } + + break; + } + + /* gote next entry */ + table++; + } + + return PEI_SIGNAL_NOT_SAVED; +} + +/*==== END OF FILE ==========================================================*/