FreeCalypso > hg > fc-magnetite
view src/g23m-gprs/gmm/gmm_pei.c @ 480:41f2cc21bca9
hybrid fw: code change to support allowing GSM APDUs in AT+CSIM
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 19 Jun 2018 06:27:16 +0000 |
parents | 219afcfc6250 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | 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 ==========================================================*/