FreeCalypso > hg > fc-tourmaline
view src/g23m-gsm/sim/sim_stk.c @ 223:740a8e8fc9d7
startup sync logic rework for the new PWON button boot scheme
Previously we added logic to the MMI task to hold off PEI init until
R2D is running, and then extended that condition to wait for FCHG
init too. However, the dependencies of MMI upon R2D and FCHG don't
start until mmiInit(), and that call is driven by Switch_ON() code,
hence the wait for R2D and FCHG init can be made in that code path
instead of the MMI task. Furthermore, with our new way of signaling
PWON button boot to MMI, we need a new wait to ensure that the MMI
task is up - previously this assurance was provided by the wait for
Kp pointers to be set.
Solution: revert our previous PEI init hold-off additions to MMI,
add a new flag indicating MMI task init done, and put the combined
wait for all needed conditions into our new PWON button boot code
in power.c.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 27 Apr 2021 06:24:52 +0000 |
parents | fa8dc04885d8 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : GSM-F&D (8411) | Modul : SIM_STK +----------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Purpose : This modul defines the SIM Toolkit Upgrade. +----------------------------------------------------------------------------- */ #ifndef SIM_STK_C #define SIM_STK_C #define ENTITY_SIM /*==== INCLUDES ===================================================*/ #include <string.h> #include "typedefs.h" #include "pcm.h" #include "pconst.cdg" #include "message.h" #include "ccdapi.h" #include "vsi.h" #include "custom.h" #include "gsm.h" #include "cnf_sim.h" #include "mon_sim.h" #include "prim.h" #include "pei.h" #include "tok.h" #include "sim.h" #include "sim_em.h" #include "cl_imei.h" /* IMEI common library */ #include "cl_shrd.h" #ifdef TI_PS_UICC_CHIPSET_15 #include "8010_136_SIMDRV_SAP_inline.h" #endif EXTERN USHORT stk_l_cmd; /*==== EXPORT =====================================================*/ /* * These Functions are only temporary valid and should be replaced as soon as possible */ EXTERN UBYTE get_network_meas (UBYTE * chan_list); EXTERN UBYTE get_bcch_chan_list (stk_data_type * out_stk_data); /*==== PRIVAT =====================================================*/ #ifdef FF_SAT_E LOCAL void stk_handle_ccd_error(UBYTE notOK, UBYTE* status, UBYTE* general_result, UBYTE* add_info_result); LOCAL void stk_bip_decode_stk_command(T_sdu* message, T_cmd_details* cmd_details, UBYTE* status, UBYTE* general_result, UBYTE* add_info_result); LOCAL void stk_close_dti_connection(UBYTE open); LOCAL void stk_close_bip_channel(UBYTE general_result, UBYTE add_info_result); /* LOCAL void stk_dti_inform_mmi_old (UBYTE dti_conn_req); */ LOCAL void stk_dti_inform_mmi(UBYTE dti_conn_req, UBYTE bip_conn_req ); LOCAL void stk_dti_send_data(); LOCAL void stk_bip_send_data_terminal_response(UBYTE general_result, UBYTE add_info_result); #endif /* FF_SAT_E */ /*==== TYPES ======================================================*/ typedef struct { UBYTE tag; UBYTE min_len; UBYTE mand; UBYTE min_req; } T_SAT_TAG_DESC; typedef struct { UBYTE cmd_type; UBYTE tp_i; UBYTE tp_flag; UBYTE max_tag; const T_SAT_TAG_DESC *tag_desc; } T_SAT_CMD_DESC; /*==== CONSTANTS ==================================================*/ const T_SAT_TAG_DESC sat_def_cmd[2] = { { STK_COMMAND_DETAILS_TAG, STK_COMMAND_DETAILS_LEN, TRUE, TRUE }, { STK_DEVICE_IDENTITY_TAG, STK_DEVICE_IDENTITY_LEN, TRUE, TRUE } }; // valid tags for any command const T_SAT_TAG_DESC sat_cmd_poll_itv[3] = { { STK_COMMAND_DETAILS_TAG, STK_COMMAND_DETAILS_LEN, TRUE, TRUE }, { STK_DEVICE_IDENTITY_TAG, STK_DEVICE_IDENTITY_LEN, TRUE, TRUE }, { STK_DURATION_TAG, STK_DURATION_LEN, TRUE, TRUE } }; // valid tags for POLL INTERVALL const T_SAT_TAG_DESC sat_cmd_refresh[3] = { { STK_COMMAND_DETAILS_TAG, STK_COMMAND_DETAILS_LEN, TRUE, TRUE }, { STK_DEVICE_IDENTITY_TAG, STK_DEVICE_IDENTITY_LEN, TRUE, TRUE }, { STK_FILE_LIST_TAG, STK_FILE_LIST_LEN, FALSE, TRUE } }; // valid tags for REFRESH const T_SAT_TAG_DESC sat_cmd_event_list[3] = { { STK_COMMAND_DETAILS_TAG, STK_COMMAND_DETAILS_LEN, TRUE, TRUE }, { STK_DEVICE_IDENTITY_TAG, STK_DEVICE_IDENTITY_LEN, TRUE, TRUE }, { STK_EVENT_LIST_TAG, STK_EVENT_LIST_LEN, TRUE, TRUE } }; // valid tags for SETUP EVENT LIST const T_SAT_TAG_DESC sat_cmd_timer[4] = { { STK_COMMAND_DETAILS_TAG, STK_COMMAND_DETAILS_LEN, TRUE, TRUE }, { STK_DEVICE_IDENTITY_TAG, STK_DEVICE_IDENTITY_LEN, TRUE, TRUE }, { STK_TIMER_ID_TAG, STK_TIMER_ID_LEN, TRUE, TRUE }, { STK_TIMER_VALUE_TAG, STK_TIMER_VALUE_LEN, FALSE, FALSE } }; // valid tags for TIMER MANAGEMENT const T_SAT_TAG_DESC sat_cmd_receive_data[5] = { { STK_COMMAND_DETAILS_TAG, STK_COMMAND_DETAILS_LEN, TRUE, TRUE }, { STK_DEVICE_IDENTITY_TAG, STK_DEVICE_IDENTITY_LEN, TRUE, TRUE }, { STK_ALPHA_IDENTITY_TAG, STK_ALPHA_IDENTITY_LEN, FALSE, FALSE }, { STK_ICON_IDENTITY_TAG, STK_ICON_IDENTITY_LEN, FALSE, FALSE }, { STK_CHANNEL_DATA_LGTH_TAG, STK_CHANNEL_DATA_LGTH_LEN, TRUE, TRUE } }; // valid tags for RECEIVE DATA const T_SAT_TAG_DESC sat_cmd_send_data[5] = { { STK_COMMAND_DETAILS_TAG, STK_COMMAND_DETAILS_LEN, TRUE, TRUE }, { STK_DEVICE_IDENTITY_TAG, STK_DEVICE_IDENTITY_LEN, TRUE, TRUE }, { STK_ALPHA_IDENTITY_TAG, STK_ALPHA_IDENTITY_LEN, FALSE, FALSE }, { STK_ICON_IDENTITY_TAG, STK_ICON_IDENTITY_LEN, FALSE, FALSE }, { STK_CHANNEL_DATA_TAG, STK_CHANNEL_DATA_LEN, TRUE, TRUE } }; // valid tags for SEND DATA const T_SAT_CMD_DESC sat_cmd_list[] = { { 0, 0, 0xFF, item_of(sat_def_cmd), sat_def_cmd }, // command not yet known { STK_REFRESH, 2, SAT_TP3_REFRESH, item_of(sat_cmd_refresh), sat_cmd_refresh }, { STK_MORE_TIME, 2, SAT_TP3_MORE_TIME, item_of(sat_def_cmd), sat_def_cmd }, { STK_POLL_INTERVALL, 2, SAT_TP3_POLL_ITV, item_of(sat_cmd_poll_itv), sat_cmd_poll_itv }, { STK_POLLING_OFF, 2, SAT_TP3_POLL_OFF, item_of(sat_def_cmd), sat_def_cmd }, { STK_SET_UP_CALL, 3, SAT_TP4_SETUP_CALL, item_of(sat_def_cmd), sat_def_cmd }, { STK_SEND_SS, 3, SAT_TP4_SEND_SS, item_of(sat_def_cmd), sat_def_cmd }, { STK_SEND_SMS, 3, SAT_TP4_SEND_SMS, item_of(sat_def_cmd), sat_def_cmd }, { STK_PLAY_TONE, 2, SAT_TP3_PLAY_TONE, item_of(sat_def_cmd), sat_def_cmd }, { STK_DISPLAY_TEXT, 2, SAT_TP3_DSPL_TXT, item_of(sat_def_cmd), sat_def_cmd }, { STK_GET_INKEY, 2, SAT_TP3_GET_INKEY, item_of(sat_def_cmd), sat_def_cmd }, { STK_GET_INPUT, 2, SAT_TP3_GET_INPUT, item_of(sat_def_cmd), sat_def_cmd }, { STK_SELECT_ITEM, 3, SAT_TP4_SEL_ITEM, item_of(sat_def_cmd), sat_def_cmd }, { STK_SET_UP_MENU, 3, SAT_TP4_SETUP_MENU, item_of(sat_def_cmd), sat_def_cmd }, { STK_PROVIDE_LOCAL_INFO, 3, SAT_TP4_PLI_PLMN_IMEI, item_of(sat_def_cmd), sat_def_cmd }, { STK_TIMER_MANAGEMENT, 7, SAT_TP8_TMNG_ST, item_of(sat_cmd_timer), sat_cmd_timer }, { STK_SETUP_EVENT_LIST, 4, SAT_TP5_EVENT_LIST, item_of(sat_def_cmd), sat_def_cmd }, { STK_SEND_USSD, 3, SAT_TP4_SEND_USSD, item_of(sat_def_cmd), sat_def_cmd }, { STK_SEND_DTMF, 8, SAT_TP9_DTMF_CMD, item_of(sat_def_cmd), sat_def_cmd }, { STK_SETUP_IDLE_TEXT, 7, SAT_TP8_IDLE_TXT, item_of(sat_def_cmd), sat_def_cmd }, { STK_RUN_AT_CMD, 7, SAT_TP8_AT_CMD, item_of(sat_def_cmd), sat_def_cmd }, { STK_LANGUAGE_NOTIFICATION, 8, SAT_TP9_LANG_NOTIFY, item_of(sat_def_cmd), sat_def_cmd } #ifdef FF_SAT_C , { STK_LAUNCH_BROWSER, 8, SAT_TP9_LAUNCH_BROWSER, item_of(sat_def_cmd), sat_def_cmd } #endif /* FF_SAT_C */ #ifdef FF_SAT_E , { STK_OPEN_CHANNEL, 11, SAT_TP12_OPEN_CHANNEL, item_of(sat_def_cmd), sat_def_cmd }, { STK_CLOSE_CHANNEL, 11, SAT_TP12_CLOSE_CHANNEL, item_of(sat_def_cmd), sat_def_cmd }, { STK_RECEIVE_DATA, 11, SAT_TP12_RECEIVE_DATA, item_of(sat_cmd_receive_data), sat_cmd_receive_data }, { STK_SEND_DATA, 11, SAT_TP12_SEND_DATA, item_of(sat_cmd_send_data), sat_cmd_send_data }, { STK_GET_CHANNEL_STAT, 11, SAT_TP12_GET_CHANNEL_STAT, item_of(sat_def_cmd), sat_def_cmd } #endif /* FF_SAT_E */ }; /* Terminal Profile bits for which SIM is exclusively responsible. They are discarded from the profile provided by MMI */ static const UBYTE sat_tp_sim_exclusive[MAX_STK_PRF] = { /* SAT_TP1_PRF_DNL |*/ SAT_TP1_TIMER_EXP | SAT_TP1_CC_ON_REDIAL, 0x0, SAT_TP3_MORE_TIME | SAT_TP3_POLL_ITV | SAT_TP3_POLL_OFF, SAT_TP4_PLI_PLMN_IMEI | SAT_TP4_PLI_NMR, 0x0 /*SAT_TP5_LOC_STATUS*/, 0x0, 0xFF, SAT_TP8_TMNG_ST | SAT_TP8_TMNG_VAL, SAT_TP9_BCCH_COD | SAT_TP9_PLI_TIMING_ADV, /* Timing Advance is to be supported */ 0x0, 0x0, SAT_TP12_RECEIVE_DATA | SAT_TP12_SEND_DATA, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFF, 0x0, 0xFF}; /* Terminal Profile bits which have to be supported by SIM to be valid with the profile provided by MMI */ static const UBYTE sat_tp_sim_ability[MAX_STK_PRF] = { SAT_TP1_PRF_DNL, SAT_TP2_CMD_RES, SAT_TP3_DSPL_TXT | SAT_TP3_GET_INKEY | SAT_TP3_GET_INPUT | SAT_TP3_PLAY_TONE | SAT_TP3_REFRESH, SAT_TP4_SEL_ITEM | SAT_TP4_SEND_SMS | SAT_TP4_SEND_SS | SAT_TP4_SEND_USSD | SAT_TP4_SETUP_CALL | SAT_TP4_SETUP_MENU, SAT_TP5_EVENT_LIST, 0x0, 0x0, SAT_TP8_IDLE_TXT | SAT_TP8_AT_CMD | SAT_TP8_PLI_DTT, SAT_TP9_DTMF_CMD | SAT_TP9_LANG_NOTIFY | SAT_TP9_LAUNCH_BROWSER, 0x0, 0x0, SAT_TP12_OPEN_CHANNEL | SAT_TP12_CLOSE_CHANNEL | SAT_TP12_GET_CHANNEL_STAT, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; /* Currently supported Terminal Profile bits by SIM */ static const UBYTE sat_tp_sim_enabled[MAX_STK_PRF] = { SAT_TP1_PRF_DNL | SAT_TP1_SMS_DNL | SAT_TP1_9E_XX | SAT_TP1_TIMER_EXP, SAT_TP2_CMD_RES, SAT_TP3_MORE_TIME | SAT_TP3_POLL_ITV | SAT_TP3_POLL_OFF | SAT_TP3_REFRESH, SAT_TP4_PLI_PLMN_IMEI | SAT_TP4_PLI_NMR, 0x0, 0x0, 0x0, SAT_TP8_TMNG_ST | SAT_TP8_TMNG_VAL | SAT_TP8_PLI_DTT | SAT_TP8_IDLE_TXT | SAT_TP8_AT_CMD, SAT_TP9_BCCH_COD | SAT_TP9_PLI_TIMING_ADV, /* Timing Advance is to be supported */ 0x0, 0x0, #ifdef FF_SAT_E SAT_TP12_OPEN_CHANNEL | SAT_TP12_CLOSE_CHANNEL | SAT_TP12_GET_CHANNEL_STAT | SAT_TP12_RECEIVE_DATA | SAT_TP12_SEND_DATA, #else 0x0, #endif 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; static const UBYTE tbl_device_src_id[] = { DEV_SRC_KBD, DEV_SRC_DSP, DEV_SRC_EAR, DEV_SRC_CDR0, DEV_SRC_CDR1, DEV_SRC_CDR2, DEV_SRC_CDR3, DEV_SRC_CDR4, DEV_SRC_CDR5, DEV_SRC_CDR6, DEV_SRC_CDR7, DEV_SRC_CH1, DEV_SRC_CH2, DEV_SRC_CH3, DEV_SRC_CH4, DEV_SRC_CH5, DEV_SRC_CH6, DEV_SRC_CH7, DEV_SRC_SIM, DEV_SRC_ME, DEV_SRC_NTW, 0 }; /*==== VARIABLES ==================================================*/ BOOL startTimerPollOff = FALSE; USHORT cusSatMinPollItv = 50; // 5 seconds /*==== FUNCTIONS ==================================================*/ LOCAL UBYTE stk_dti_bip_receive_data (T_sdu* message, UBYTE result_code); /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_init_sim_data | +--------------------------------------------------------------------+ PURPOSE : Initialize the SIM data for the module SIM TOOLKIT. */ GLOBAL void stk_init_sim_data (void) { TRACE_FUNCTION ("stk_init_sim_data()"); /* * initialize SAT variables */ sim_data.sat_session = FALSE; sim_data.ext_sat_cmd = FALSE; sim_data.term_resp_sent = FALSE; sim_data.chk_sat_avail = FALSE; sim_data.context_switch_ptr = NULL; sim_data.cust_mode = FALSE; sim_data.user_confirmation_expected = FALSE; #ifdef FF_SAT_E /* * initialize DTI variables */ sim_data.dti_connection_state = SIM_DTI_CONNECTION_CLOSED; sim_data.dti_rx_state = SIM_DTI_RX_IDLE; sim_data.dti_tx_state = SIM_DTI_TX_IDLE; sim_data.event_data_avail = SIM_EVENT_DISABLE; sim_data.bip_state = SIM_BIP_CLOSED; sim_data.bip_suspend = FALSE; #ifdef _SIMULATION_ TRACE_EVENT("bip_rx_state = IDLE"); #endif sim_data.bip_rx_state = SIM_BIP_RX_IDLE; #ifdef _SIMULATION_ TRACE_EVENT("bip_tx_state = IDLE"); #endif sim_data.bip_tx_state = SIM_BIP_TX_IDLE; sim_data.bip_timer_state = SIM_BIP_TIMER_DISCONNECTED; sim_data.bip_release_time = SIM_NO_AUTO_RELEASE; sim_data.bip_general_result = RSLT_PERF_SUCCESS; sim_data.bip_add_info_result = ADD_NO_CAUSE; sim_data.con_type = SIM_CON_TYPE_UDP; sim_data.data_to_send.first = (ULONG)NULL; sim_data.data_to_send.list_len = 0; sim_data.prev_data_to_send.first = (ULONG)NULL; sim_data.prev_data_to_send.list_len = 0; sim_data.received_data.first = (ULONG)NULL; sim_data.received_data.list_len = 0; sim_data.received_data_pos = 0; sim_data.sim_dti_req = NULL; sim_data.sim_bip_req = NULL; sim_data.sim_bip_config_req = NULL; memset(&sim_data.udp_parameters, 0, sizeof(T_SRC_DES)); #endif /* FF_SAT_E */ } /* stk_init_sim_data() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_check_tp | +--------------------------------------------------------------------+ PURPOSE : Evaluates the received Terminal Profile against the capability of the SIM Entity. */ GLOBAL void stk_check_tp (UBYTE *out_prf, UBYTE *in_prf, USHORT len) { int i; UBYTE tp_tmp; /* TRACE_FUNCTION ("stk_check_tp()"); */ len = MINIMUM(len, MAX_STK_PRF); for (i = 0; i < len; i++) // check TP from MMI { #ifndef __OLD tp_tmp = sat_tp_sim_enabled[i] & ~sat_tp_sim_ability[i]; out_prf[i] = ((in_prf[i] & ~sat_tp_sim_exclusive[i]) & ~tp_tmp) | tp_tmp; #else out_prf[i] = ((in_prf[i] & ~sat_tp_sim_exclusive[i]) & (sat_tp_sim_enabled[i] | ~sat_tp_sim_ability[i])) | sat_tp_sim_enabled[i]; #endif } if (!(out_prf[0] & SAT_TP1_SMS_DNL)) // check SMS download out_prf[0] &= ~SAT_TP1_9E_XX; // only valid with SMS download if (len >= 6 AND !(out_prf[4] & SAT_TP5_EVENT_LIST)) // check event list consistency out_prf[5] = out_prf[4] = 0; // discard event list if (len >= 12 AND (out_prf[11] & STK_TP12_CLASS_E) NEQ STK_TP12_CLASS_E) { out_prf[11] &= ~STK_TP12_CLASS_E; if (len >= 13) out_prf[12] &= ~(SAT_TP13_CSD_SUPP_BY_ME | SAT_TP13_GPRS_SUPP_BY_ME); if (len >= 17) out_prf[16] &= ~(SAT_TP17_BEARER_IND_SUPP_TCP | SAT_TP17_BEARER_IND_SUPP_UDP); } TRACE_EVENT_P5("TP: %02X %02X %02X %02X ... (%d bytes)", out_prf[0], out_prf[1], out_prf[2], out_prf[3], len); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_perform_profile_download | +--------------------------------------------------------------------+ PURPOSE : Initialize the SIM data for the module application. */ GLOBAL void stk_perform_profile_download (void) { USHORT result; USHORT used_tp = (USHORT)sizeof (sim_data.stk_profile); TRACE_FUNCTION ("stk_perform_profile_download()"); do { if (sim_data.stk_profile[--used_tp] NEQ 0) break; } while (used_tp >= 3); used_tp++; if ((result = FKT_TerminalProfile (sim_data.stk_profile, used_tp)) NEQ SIM_NO_ERROR) { TRACE_EVENT_P1("TP dnl error: %04X", result); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_proactive_polling | +--------------------------------------------------------------------+ PURPOSE : Polling of an proactive SIM card. */ static const UBYTE tag_dur [] = { STK_DURATION_TAG | STK_COMPREHENSION_REQUIRED, /* duration tag */ STK_DURATION_LEN, /* duration length */ 0, /* unit */ 0 /* number of units */ }; static const UBYTE terminal_response_loci [21] = { STK_COMMAND_DETAILS_TAG | STK_COMPREHENSION_REQUIRED, /* command details tag */ STK_COMMAND_DETAILS_LEN, /* command details length */ 0, /* command number */ STK_PROVIDE_LOCAL_INFO, /* command PROVIDE LOCATION INFO*/ 0, /* location information */ STK_DEVICE_IDENTITY_TAG | STK_COMPREHENSION_REQUIRED, /* device details tag */ STK_DEVICE_IDENTITY_LEN, /* device details length */ 0x82, /* source ME */ 0x81, /* destination SIM */ STK_RESULT_TAG | STK_COMPREHENSION_REQUIRED, /* result tag */ 1, /* result length */ 0, /* result OK */ 0x13, /* location information tag */ 7, /* location information length */ 0,0,0, /* MCC & MNC */ 0,0, /* Location area code */ 0,0 /* cell identity */ }; static const UBYTE terminal_response_imei [22] = { STK_COMMAND_DETAILS_TAG | STK_COMPREHENSION_REQUIRED, /* command details tag */ STK_COMMAND_DETAILS_LEN, /* command details length */ 0, /* command number */ STK_PROVIDE_LOCAL_INFO, /* command PROVIDE LOCATION INFO*/ 1, /* imei */ STK_DEVICE_IDENTITY_TAG | STK_COMPREHENSION_REQUIRED, /* device details tag */ STK_DEVICE_IDENTITY_LEN, /* device details length */ 0x82, /* source ME */ 0x81, /* destination SIM */ STK_RESULT_TAG | STK_COMPREHENSION_REQUIRED, /* result tag */ 1, /* result length */ 0, /* result OK */ 0x14, /* imei tag */ 8, /* imei length */ 0,0,0,0,0,0,0,0 /* imei digits */ }; static const UBYTE terminal_response_nmr [14] = { STK_COMMAND_DETAILS_TAG | STK_COMPREHENSION_REQUIRED, /* command details tag */ STK_COMMAND_DETAILS_LEN, /* command details length */ 0, /* command number */ STK_PROVIDE_LOCAL_INFO, /* command PROVIDE LOCATION INFO*/ 2, /* network measurement results */ STK_DEVICE_IDENTITY_TAG | STK_COMPREHENSION_REQUIRED, /* device details tag */ STK_DEVICE_IDENTITY_LEN, /* device details length */ 0x82, /* source ME */ 0x81, /* destination SIM */ STK_RESULT_TAG | STK_COMPREHENSION_REQUIRED, /* result tag */ 1, /* result length */ 0, /* result OK */ 0x16, /* nmr tag */ 16 /* nmr length */ }; /* * Terminal-Response for timing advance */ static const UBYTE terminal_response_timingadv [16] = { /* ---- cmd details ----- */ STK_COMMAND_DETAILS_TAG | STK_COMPREHENSION_REQUIRED, /* command details tag */ STK_COMMAND_DETAILS_LEN, /* command details length */ 0, /* command number */ STK_PROVIDE_LOCAL_INFO, /* command PROVIDE LOCAL INFO */ 5, /* timing advance */ /* ---- device ids ------ */ STK_DEVICE_IDENTITY_TAG | STK_COMPREHENSION_REQUIRED, /* device details tag */ STK_DEVICE_IDENTITY_LEN, /* device details length */ 0x82, /* source ME */ 0x81, /* destination SIM */ /* ------result --------- */ STK_RESULT_TAG | STK_COMPREHENSION_REQUIRED, /* result tag */ 1, /* result length */ 0, /* result OK */ /* --- timing advance --- */ 0x2E, /* timing advance tag */ 2, /* timing advance len */ 0, /* ME Status */ 0 /* Timing Advance */ }; static const T_SIM_TRSP_SIMPLE terminal_response_def = { STK_COMMAND_DETAILS_TAG | STK_COMPREHENSION_REQUIRED, /* command details tag */ STK_COMMAND_DETAILS_LEN, /* command details length */ 0, /* command number */ 0, /* command type place holder */ 0, /* command qualifier */ STK_DEVICE_IDENTITY_TAG | STK_COMPREHENSION_REQUIRED, /* device details tag */ STK_DEVICE_IDENTITY_LEN, /* device details length */ 0x82, /* source ME */ 0x81, /* destination SIM */ STK_RESULT_TAG | STK_COMPREHENSION_REQUIRED, /* result tag */ 1, /* result length place holder */ 0xFF, /* result place holder */ 0, /* result additional info */ }; #ifdef __INVALID static const UBYTE terminal_response_ok [12] = { STK_COMMAND_DETAILS_TAG | STK_COMPREHENSION_REQUIRED, /* command details tag */ STK_COMMAND_DETAILS_LEN, /* command details length */ 0, /* command number */ 2, /* command MORE TIME */ 0, /* not used */ STK_DEVICE_IDENTITY_TAG | STK_COMPREHENSION_REQUIRED, /* device details tag */ STK_DEVICE_IDENTITY_LEN, /* device details length */ 0x82, /* source ME */ 0x81, /* destination SIM */ STK_RESULT_TAG | STK_COMPREHENSION_REQUIRED, /* result tag */ 1, /* result length */ 0 /* result OK */ }; static const UBYTE terminal_response_loci_neg [13] = { STK_COMMAND_DETAILS_TAG | STK_COMPREHENSION_REQUIRED, /* command details tag */ STK_COMMAND_DETAILS_LEN, /* command details length */ 0, /* command number */ STK_PROVIDE_LOCAL_INFO, /* command PROVIDE LOCATION INFO*/ 0, /* location information */ STK_DEVICE_IDENTITY_TAG | STK_COMPREHENSION_REQUIRED, /* device details tag */ STK_DEVICE_IDENTITY_LEN, /* device details length */ 0x82, /* source ME */ 0x81, /* destination SIM */ STK_RESULT_TAG | STK_COMPREHENSION_REQUIRED, /* result tag */ 2, /* result length */ 0x20, /* result ME unable to process */ 4 /* result add. info no service */ }; static const UBYTE terminal_response_no_cap [12] = { STK_COMMAND_DETAILS_TAG | STK_COMPREHENSION_REQUIRED, /* command details tag */ STK_COMMAND_DETAILS_LEN, /* command details length */ 0, /* command number */ 0x26, /* command PROVIDE LOCATION INFO*/ 0, /* location information */ 2, /* device details tag */ 2, /* device details length */ 0x82, /* source ME */ 0x81, /* destination SIM */ 3, /* result tag */ 1, /* result length */ 0x30 /* result beyond ME capability */ }; #endif LOCAL UBYTE stk_process_tl (UBYTE **pp_stk, SHORT *p_ber_len, SHORT *p_tlv_len) { /* get tag and length and adjust pointer to get parameter values */ UBYTE tag = STK_COMPREHENSION_REQUIRED; SHORT tlv_len; if (*p_ber_len >= 2) { tag = *((*pp_stk)++); // get tag and adjust pointer if ((tlv_len = (SHORT)*((*pp_stk)++)) <= 0x7F) { // one byte length *p_tlv_len = tlv_len; // get length *p_ber_len -= 2; } else if (tlv_len EQ 0x81 AND *p_ber_len >= 3) { // two bytes length *p_tlv_len = (SHORT)*((*pp_stk)++); *p_ber_len -= 3; // get length and adjust pointer } else { // erroneous length coding *p_tlv_len = 0; *p_ber_len = 0; return STK_COMPREHENSION_REQUIRED; } } return tag; } LOCAL SHORT stk_build_response (UBYTE *p_response, UBYTE *p_cmd, int cmd_len, UBYTE *p_res, int res_len, UBYTE *p_prm, int prm_len) { /* * builds a TERMINAL RESPONSE */ static const UBYTE dev_resp[5] = { STK_DEVICE_IDENTITY_TAG | STK_COMPREHENSION_REQUIRED, /* device details tag */ STK_DEVICE_IDENTITY_LEN, /* device details length */ 0x82, /* source ME */ 0x81, /* destination SIM */ STK_RESULT_TAG | STK_COMPREHENSION_REQUIRED /* result tag */ }; int tr_len = 6; #ifdef _SIMULATION_ TRACE_FUNCTION ("stk_build_response()"); #endif TRACE_FUNCTION_P1 ("TERMINAL_RESPONSE: result=0x%02X", (int)*p_res); memcpy (p_response, p_cmd, cmd_len); memcpy (p_response + cmd_len, dev_resp, 5); p_response[cmd_len + 5] = (UBYTE)res_len; memcpy (p_response + cmd_len + 6, p_res, res_len); tr_len += cmd_len + res_len; if (p_prm NEQ NULL AND prm_len > 0) { memcpy (p_response + tr_len, p_prm, prm_len); tr_len += prm_len; } return (SHORT)tr_len; } GLOBAL int process_sim_refresh( T_CONTEXT_SWITCH *cmd_ptr ) { int i; SHORT resp_len = 0; #ifdef TI_PS_UICC_CHIPSET_15 U8 readerId = SIMDRV_VAL_READER_ID__RANGE_MIN; U8 voltageSelect = SIMDRV_REQ_VOLTAGE_SEL; #endif T_STK_POLL_DATA *p; MALLOC (p, sizeof (T_STK_POLL_DATA)); memset (p, 0, sizeof (T_STK_POLL_DATA)); TRACE_FUNCTION ("process_sim_refresh()"); /* process as before */ switch (cmd_ptr->p_cmd[4]) { case 1: /*check file list is empty */ if( ( 0 == cmd_ptr->fl_len ) OR ( 1 == cmd_ptr->fl_len ) ) { cmd_ptr->res_code[0] = STK_RES_ERR_MISS_VALUE; resp_len = stk_build_response (p->response, cmd_ptr->p_cmd, (int)cmd_ptr->cmd_len, cmd_ptr->res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("FCN: File List is empty"); #endif FKT_TerminalResponse (p->response, (USHORT)resp_len); break; } if (cmd_ptr->tag2 NEQ NULL AND cmd_ptr->fl_len >= 5) { BOOL sim_init = FALSE; PALLOC (file_update_sms, SIM_FILE_UPDATE_IND); memset (file_update_sms, 0, sizeof(T_SIM_FILE_UPDATE_IND)); file_update_sms->val_nr = *(cmd_ptr->tag2++); cmd_ptr->fl_len -= 3; /* align file id count */ for (i = 0; cmd_ptr->fl_len > 0 AND i < (int)file_update_sms->val_nr; i++) { do { cmd_ptr->tag2 += 2; /* Check if entry is a first level directory */ if(cmd_ptr->tag2[0] EQ 0x7F) { if(file_update_sms->file_info[i].v_path_info EQ FALSE) { file_update_sms->file_info[i].v_path_info = TRUE; file_update_sms->file_info[i].path_info.df_level1 = ((USHORT)cmd_ptr->tag2[0] << 8) | (USHORT)cmd_ptr->tag2[1]; } else { /* This has already been filled. There cannot be another first level directory. Since i is reduced, i will not equal to file_update_sms->val_nr and error will be sent to SIM */ i--; break; } } /* Check if entry is a second level directory and first level * directory is also filled*/ else if(cmd_ptr->tag2[0] EQ 0x5F) { if(file_update_sms->file_info[i].v_path_info EQ TRUE AND file_update_sms->file_info[i].path_info.v_df_level2 EQ FALSE) { file_update_sms->file_info[i].path_info.v_df_level2 = TRUE; file_update_sms->file_info[i].path_info.df_level2 = ((USHORT)cmd_ptr->tag2[0] << 8) | (USHORT)cmd_ptr->tag2[1]; } else { /* This has already been filled. There cannot be another second level directory */ i--; break; } } cmd_ptr->fl_len -= 2; } while (cmd_ptr->fl_len > 0 AND cmd_ptr->tag2[2] NEQ 0x3F); if (cmd_ptr->tag2[0] NEQ 0x2F AND cmd_ptr->tag2[0] NEQ 0x6F AND cmd_ptr->tag2[0] NEQ 0x4F) break; /* no EF code -> loop exit leads to error response */ file_update_sms->file_info[i].datafield = ((USHORT)cmd_ptr->tag2[0] << 8) | (USHORT)cmd_ptr->tag2[1]; if ((file_update_sms->file_info[i].datafield EQ SIM_PHASE) OR (file_update_sms->file_info[i].datafield EQ SIM_SST)) { /* SIM initialisation is needed! */ sim_init = TRUE; TRACE_FUNCTION ("FCN converted to INIT"); /* break; exit for loop */ } } if (cmd_ptr->fl_len > 0 OR i NEQ (int)file_update_sms->val_nr) { /* inconsistent TLV content */ PFREE(file_update_sms); cmd_ptr->res_code[0] = STK_RES_ERR_CMD_DATA; resp_len = stk_build_response (p->response, cmd_ptr->p_cmd, (int)cmd_ptr->cmd_len, cmd_ptr->res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("FCN: inconsistent TLV content"); #endif FKT_TerminalResponse (p->response, (USHORT)resp_len); break; /* exit switch 'cmd_qual' */ } if (!sim_init) { { PALLOC (file_update_mmi, SIM_FILE_UPDATE_IND); memcpy (file_update_mmi, file_update_sms, sizeof(T_SIM_FILE_UPDATE_IND)); PSENDX (MMI, file_update_mmi); } { PALLOC (file_update_mm, SIM_FILE_UPDATE_IND); memcpy (file_update_mm, file_update_sms, sizeof(T_SIM_FILE_UPDATE_IND)); PSENDX (MM, file_update_mm); } PSENDX (SMS, file_update_sms); sim_data.file_change_resp = 0x7; /* check response */ /* Force file selection */ sim_data.act_directory = NOT_PRESENT_16BIT; sim_data.act_field = NOT_PRESENT_16BIT; if ((USHORT)(cmd_ptr->cmd_len + 7) <= sizeof (sim_data.stk_response)) { sim_data.stk_resp_len = stk_build_response (sim_data.stk_response, cmd_ptr->p_cmd, (int)cmd_ptr->cmd_len, cmd_ptr->res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("FCN: prepare TR"); #endif } else sim_data.stk_resp_len = 0; break; } else { PFREE (file_update_sms); } } else { cmd_ptr->res_code[0] = STK_RES_ERR_MISS_VALUE; resp_len = stk_build_response (p->response, cmd_ptr->p_cmd, (int)cmd_ptr->cmd_len, cmd_ptr->res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("FCN: cmd incomplete"); #endif FKT_TerminalResponse (p->response, (USHORT)resp_len); break; } // no break for sim_init EQ TRUE ! case 3: case 2: if (cmd_ptr->res_code[0] EQ STK_RES_SUCCESS) // do not overwrite special result codes // these commands read more EFs than indicated cmd_ptr->res_code[0] = STK_RES_SUCC_ADD_EF_READ; case 0: if ( (SIM_IS_FLAG_SET (CALL_ACTIVE)) AND (sim_data.cust_mode EQ 0) ) { cmd_ptr->res_code[0] = STK_RES_BUSY_ME; cmd_ptr->res_code[1] = STK_RES_EXT_BUSY_CALL; resp_len = stk_build_response (p->response, cmd_ptr->p_cmd, (int)cmd_ptr->cmd_len, cmd_ptr->res_code, 2, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("INIT: call active"); #endif FKT_TerminalResponse (p->response, (USHORT)resp_len); } else { /* Force file selection */ sim_data.act_directory = NOT_PRESENT_16BIT; sim_data.act_field = NOT_PRESENT_16BIT; sim_data.status_time = THIRTY_SECONDS; app_sim_read_parameters (); /* The terminal response to be sent is created and stored in context. Once ACI and MM indicates the completion of the reading of the EFs through SIM_SYNC_REQ, the response will be sent. */ sim_data.stk_resp_len = stk_build_response (sim_data.stk_response, cmd_ptr->p_cmd, (int)cmd_ptr->cmd_len, cmd_ptr->res_code, 1, NULL, 0); sim_data.sync_awaited = SIM_SYNC_AWAIT_MM_READ | SIM_SYNC_AWAIT_MMI_READ; #ifdef _SIMULATION_ TRACE_EVENT("INIT: success"); #endif } break; case 4: if ( (SIM_IS_FLAG_SET (CALL_ACTIVE)) AND (sim_data.cust_mode EQ 0) ) { cmd_ptr->res_code[0] = STK_RES_BUSY_ME; cmd_ptr->res_code[1] = STK_RES_EXT_BUSY_CALL; resp_len = stk_build_response (p->response, cmd_ptr->p_cmd, (int)cmd_ptr->cmd_len, cmd_ptr->res_code, 2, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("RESET: call active"); #endif FKT_TerminalResponse (p->response, (USHORT)resp_len); } else { #ifndef TI_PS_UICC_CHIPSET_15 T_SIM_CARD sim_info; #endif /* TI_PS_UICC_CHIPSET_15 */ USHORT retcode; TRACE_ASSERT (cmd_ptr->sig_ptr); PFREE (cmd_ptr->sig_ptr); TRACE_ASSERT (p); MFREE (p); sim_data.remove_error = SIM_NO_ERROR; app_sim_remove (); sim_data.remove_error = SIM_CAUSE_CARD_REMOVED; #ifndef TI_PS_UICC_CHIPSET_15 SIM_PowerOff (); #else simdrv_poweroff(readerId); #endif /* Force file selection */ sim_data.act_directory = NOT_PRESENT_16BIT; sim_data.act_field = NOT_PRESENT_16BIT; /*retcode = SIM_Restart (&sim_info); Driver does not call 'insert()'! */ #ifndef TI_PS_UICC_CHIPSET_15 retcode = SIM_Reset (&sim_info); #else retcode = simdrv_reset (readerId,voltageSelect); #endif TRACE_EVENT_P1 ("Result SIM Restart = %d", (int)retcode); TRACE_FUNCTION ("process_sim_refresh() exited(1)"); return(1); //return and exit stk_proactive_polling(), if that is where called from } break; default: /* * not supported information request */ TRACE_FUNCTION ("process_sim_refresh() default:"); cmd_ptr->res_code[0] = STK_RES_ERR_CMD_TYPE; resp_len = stk_build_response (p->response, cmd_ptr->p_cmd, cmd_ptr->cmd_len, cmd_ptr->res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("RFR: unknown qualifier"); #endif FKT_TerminalResponse (p->response, (USHORT)resp_len); break; } TRACE_ASSERT (cmd_ptr->sig_ptr); PFREE (cmd_ptr->sig_ptr); TRACE_ASSERT (p); MFREE (p); TRACE_FUNCTION ("process_sim_refresh() exited(0)"); return(0); } GLOBAL void stk_proactive_polling (void) { UBYTE *stk, *p_tag, *p_cmd = NULL; UBYTE *found_tag[STK_MAX_EXP_TAG]; UBYTE compreh = 0, cmd_nr = 0, cmd_type, cmd_qual = 0; SHORT ber_len, tag_len, cmd_len, fl_len = 0, resp_len = 0; SHORT i, tag_i, cmd_i, tlv_len; const T_SAT_TAG_DESC *p_tag_desc; int offset; T_LOC_INFO loc_info; T_TIM_ADV tim_adv; TRACE_FUNCTION ("stk_proactive_polling()"); if (SIM_IS_FLAG_SET (PRO_ACTIVE_SIM)) { while (sim_data.proactive_sim_data_len > 0) { UINT in_queue, out_queue; UBYTE result = FALSE; UBYTE res_code[2] = {STK_RES_SUCCESS, 0}; T_TIME tm_val; T_STK_POLL_DATA *p; PALLOC (sim_toolkit_ind, SIM_TOOLKIT_IND); MALLOC (p, sizeof (T_STK_POLL_DATA)); /* * clear indication primitive */ memset (sim_toolkit_ind, 0, sizeof (T_SIM_TOOLKIT_IND)); sim_toolkit_ind->stk_cmd.l_cmd = ((USHORT)sim_data.proactive_sim_data_len) << 3; ber_len = (SHORT)sim_data.proactive_sim_data_len; sim_data.proactive_sim_data_len = 0; sim_data.term_resp_sent = FALSE; if (FKT_Fetch(sim_toolkit_ind->stk_cmd.cmd, ber_len) EQ SIM_NO_ERROR) { UBYTE tag; BOOL tag_not_found = TRUE; #ifdef _SIMULATION_ TRACE_EVENT("FKT_Fetch_EQ_SIM_NO_ERROR"); /* for debug purpose only */ #endif sim_data.ext_sat_cmd = FALSE; /* internal command by default */ stk = sim_toolkit_ind->stk_cmd.cmd; memset (found_tag, 0, sizeof(found_tag)); tag_i = cmd_i = 0; cmd_len = 0; cmd_type = 0; tag = stk_process_tl(&stk, &ber_len, &tlv_len); /* BER tag */ if (tag NEQ STK_PROACTIVE_SIM_COMMAND_TAG) { res_code[0] = STK_RES_ERR_MISS_VALUE; } else if (ber_len >= tlv_len) { ber_len = tlv_len; // omit data after BER-TLV result = TRUE; } else /* ber_len < tlv_len */ { if (tlv_len > 2) { res_code[0] = STK_RES_ERR_MISS_VALUE; result = TRUE; } else { res_code[0] = STK_RES_ERR_CMD_DATA; } } while (result AND ber_len > 0) // tag and length needed { UBYTE tag_simple; p_tag = stk; // begin of TLV tag_len = ber_len; tag_simple = stk_process_tl(&stk, &ber_len, &tlv_len); if (ber_len < tlv_len) // inconsistent length { if (res_code[0] NEQ STK_RES_ERR_MISS_VALUE) { TRACE_EVENT("ber_len < tlv_len -> STK_RES_ERR_CMD_DATA"); res_code[0] = STK_RES_ERR_CMD_DATA; } result = FALSE; break; } else ber_len -= tlv_len; // remaining BER-TLV tag_len -= ber_len; // length of TLV if (tag EQ (tag_simple & ~STK_COMPREHENSION_REQUIRED)) { #ifdef _SIMULATION_ TRACE_EVENT("TC_505A, TC_505B, TC_505C"); #endif stk += tlv_len; continue; } else { tag = tag_simple; tag_not_found = FALSE; } compreh = tag & STK_COMPREHENSION_REQUIRED; tag &= ~STK_COMPREHENSION_REQUIRED; do { p_tag_desc = &sat_cmd_list[cmd_i].tag_desc[tag_i]; if (tag EQ p_tag_desc->tag) { break; /* tag found !!! */ } else if (!p_tag_desc->mand) { tag_i++; /* skip non-mandatory tags */ } else /* mandatory tag missed */ { i = tag_i; res_code[0] = STK_RES_ERR_MISS_VALUE; while (i < (int)sat_cmd_list[cmd_i].max_tag) { p_tag_desc = &sat_cmd_list[cmd_i].tag_desc[i++]; if (tag EQ p_tag_desc->tag AND !p_tag_desc->mand) { #ifdef _SIMULATION_ TRACE_EVENT("TC_506"); #endif res_code[0] = STK_RES_ERR_CMD_DATA; break; } } if (!compreh AND i EQ (int)sat_cmd_list[cmd_i].max_tag) { #ifdef _SIMULATION_ TRACE_EVENT("TC_507"); #endif res_code[0] = STK_RES_SUCC_PART_COMPR; tag_not_found = TRUE; } break; } } while (tag_i < (int)sat_cmd_list[cmd_i].max_tag OR res_code[0]); if (tag_i >= (int)sat_cmd_list[cmd_i].max_tag) { i = (int)sat_cmd_list[cmd_i].tp_i; if ((~sat_tp_sim_ability[i] & sat_cmd_list[cmd_i].tp_flag) EQ 0) { break; /* the commmand is being handled outside the SIM */ } if (compreh) { #ifdef _SIMULATION_ TRACE_EVENT("TC_502C, TC_504"); #endif res_code[0] = STK_RES_ERR_CMD_DATA; result = FALSE; break; } } else { p_tag_desc = &sat_cmd_list[cmd_i].tag_desc[tag_i]; if (tag NEQ p_tag_desc->tag OR tlv_len < p_tag_desc->min_len) { if (compreh) { #ifdef _SIMULATION_ TRACE_EVENT("TC_503, TC_506"); #endif result = FALSE; break; } } else found_tag[tag_i] = stk; // points to parameters of tag } if (tag_not_found) { stk += tlv_len; continue; } switch (tag) { case STK_COMMAND_DETAILS_TAG: p_cmd = p_tag; // for TERMINAL RESPONSE cmd_len = tag_len; cmd_nr = stk[0]; cmd_type = stk[1]; cmd_qual = stk[2]; TRACE_FUNCTION_P2("COMMAND_DETAILS: type=0x%02X, qlf=0x%02X", (int)cmd_type, (int) cmd_qual); SIM_EM_PROACTIVE_COMMAND; for (i = 1; i < (SHORT)item_of(sat_cmd_list); i++) /* find out if known command */ { if (cmd_type EQ sat_cmd_list[i].cmd_type) { cmd_i = i; break; } } if (i EQ item_of(sat_cmd_list)) { TRACE_EVENT_P1("UNKNOWN COMMAND TYPE:0x%02X", cmd_type); } break; case STK_DEVICE_IDENTITY_TAG: #ifdef _SIMULATION_ TRACE_EVENT("found SIMPLE_TAG: STK_DEVICE_IDENTITY_TAG"); #endif break; case STK_CHANNEL_DATA_TAG: #ifdef _SIMULATION_ TRACE_EVENT("found SIMPLE_TAG: STK_CHANNEL_DATA_TAG"); #endif break; case STK_CHANNEL_DATA_LGTH_TAG: #ifdef _SIMULATION_ TRACE_EVENT("found SIMPLE_TAG: STK_CHANNEL_DATA_LGTH_TAG"); #endif break; case STK_FILE_LIST_TAG: fl_len = tlv_len; break; default: #ifdef _SIMULATION_ TRACE_EVENT_P1("other tag=0x%02X", tag); #endif break; } if (++tag_i >= STK_MAX_EXP_TAG) /* incremented index points to next tag_desc entry */ break; stk += tlv_len; } if (!result) { if (found_tag[0] EQ 0) { switch (res_code[0]) { case STK_RES_ERR_MISS_VALUE: #ifdef _SIMULATION_ TRACE_EVENT("TC_501, TC_508"); #endif memcpy (p->response, &terminal_response_def, SAT_TRSP_MIN_RES); ((T_SIM_TRSP_SIMPLE *)p->response)->cmd_nr = cmd_nr; ((T_SIM_TRSP_SIMPLE *)p->response)->cmd_type = cmd_type; ((T_SIM_TRSP_SIMPLE *)p->response)->res_gnrl = res_code[0]; FKT_TerminalResponse (p->response, SAT_TRSP_MIN_RES); break; default: break; } } else if (found_tag[0] AND cmd_i NEQ 0) { switch (res_code[0]) { case STK_RES_ERR_CMD_DATA: #ifdef _SIMULATION_ TRACE_EVENT("TC_502A, TC_502B, TC_502C, TC_506"); #endif memcpy (p->response, &terminal_response_def, SAT_TRSP_MIN_RES); ((T_SIM_TRSP_SIMPLE *)p->response)->cmd_nr = cmd_nr; ((T_SIM_TRSP_SIMPLE *)p->response)->cmd_type = cmd_type; ((T_SIM_TRSP_SIMPLE *)p->response)->res_gnrl = res_code[0]; FKT_TerminalResponse (p->response, SAT_TRSP_MIN_RES); break; case STK_RES_ERR_MISS_VALUE: #ifdef _SIMULATION_ TRACE_EVENT("TC_503, TC_509A"); #endif memcpy (p->response, &terminal_response_def, SAT_TRSP_MIN_RES); ((T_SIM_TRSP_SIMPLE *)p->response)->cmd_nr = cmd_nr; ((T_SIM_TRSP_SIMPLE *)p->response)->cmd_type = cmd_type; ((T_SIM_TRSP_SIMPLE *)p->response)->res_gnrl = res_code[0]; FKT_TerminalResponse (p->response, SAT_TRSP_MIN_RES); break; default: break; } } else if (cmd_i EQ 0) { #ifdef _SIMULATION_ TRACE_EVENT("TC_504"); #endif res_code[0] = STK_RES_ERR_CMD_TYPE; memcpy (p->response, &terminal_response_def, SAT_TRSP_MIN_RES); ((T_SIM_TRSP_SIMPLE *)p->response)->cmd_nr = cmd_nr; ((T_SIM_TRSP_SIMPLE *)p->response)->cmd_type = cmd_type; ((T_SIM_TRSP_SIMPLE *)p->response)->res_gnrl = res_code[0]; FKT_TerminalResponse (p->response, SAT_TRSP_MIN_RES); } else { resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("SAT: other error"); #endif FKT_TerminalResponse (p->response, (USHORT)resp_len); } PFREE (sim_toolkit_ind); } else switch (cmd_type) { case STK_DISPLAY_TEXT: case STK_GET_INKEY: case STK_GET_INPUT: case STK_PLAY_TONE: case STK_SET_UP_MENU: case STK_SELECT_ITEM: case STK_SEND_SMS: case STK_SEND_SS: case STK_SET_UP_CALL: case STK_SETUP_EVENT_LIST: case STK_SEND_USSD: case STK_SEND_DTMF: case STK_SETUP_IDLE_TEXT: case STK_LAUNCH_BROWSER: case STK_RUN_AT_CMD: case STK_LANGUAGE_NOTIFICATION: #ifdef FF_SAT_E case STK_OPEN_CHANNEL: case STK_CLOSE_CHANNEL: case STK_GET_CHANNEL_STAT: #endif /* FF_SAT_E */ /* * Operations processed by MMI / MFW */ sim_data.sat_session = TRUE; sim_data.ext_sat_cmd = TRUE; PSENDX (MMI, sim_toolkit_ind); break; case STK_POLL_INTERVALL: /* * SIM toolkit defines an idle poll interval. The timer in * SIM application is stopped and started with the * new value. A terminal response with the used time * is sent to SIM toolkit. */ if (found_tag[2] NEQ NULL) { BOOL org_val; TRACE_EVENT("Idle Polling switched on"); if (found_tag[2][1] NEQ 0) /* value not "reserved" */ { switch (found_tag[2][0]) { case 0: /* minutes */ if ((ULONG)found_tag[2][1] * 600L >= (ULONG)cusSatMinPollItv) { sim_data.status_time = ((T_TIME)found_tag[2][1]) * 60L * 1000 - TIMER_LATENCY; org_val = TRUE; } else org_val = FALSE; break; case 1: /* seconds */ if ((USHORT)found_tag[2][1] * 10 >= cusSatMinPollItv) { sim_data.status_time = ((T_TIME)found_tag[2][1]) * 1000L - TIMER_LATENCY; org_val = TRUE; } else org_val = FALSE; break; case 2: /* tenth seconds */ if ((USHORT)found_tag[2][1] >= cusSatMinPollItv) { sim_data.status_time = ((T_TIME)found_tag[2][1]) * 100L - TIMER_LATENCY; org_val = TRUE; } else org_val = FALSE; break; default: /* command data not understood */ res_code[0] = STK_RES_ERR_CMD_DATA; org_val = TRUE; break; /* return original values */ } } else /* return original values */ { res_code[0] = STK_RES_ERR_CMD_DATA; org_val = TRUE; } resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, (UBYTE *)tag_dur, sizeof(tag_dur)); #ifdef _SIMULATION_ TRACE_EVENT("POLL_ITV data not understood"); #endif if (org_val) { p->response[cmd_len+ 9] = found_tag[2][0]; /* copy unit */ /* copy number of units (1 to 255) or 0 !!! */ p->response[cmd_len+10] = found_tag[2][1]; } else { sim_data.status_time = ((T_TIME)cusSatMinPollItv) * 100L - TIMER_LATENCY; if (cusSatMinPollItv < 0x100) { p->response[cmd_len+ 9] = 2; // fits to tenth of seconds p->response[cmd_len+10] = (UBYTE)cusSatMinPollItv; } else if (cusSatMinPollItv < (0x100*10)) { p->response[cmd_len+ 9] = 1; // fits to seconds p->response[cmd_len+10] = (UBYTE)((cusSatMinPollItv / 5 + 1) / 2); } else { p->response[cmd_len+ 9] = 0; // fits to minutes p->response[cmd_len+10] = (UBYTE)((cusSatMinPollItv / 300 + 1) / 2); } } sim_data.idle_polling = TRUE; } else { res_code[0] = STK_RES_ERR_MISS_VALUE; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("POLL_ITV missing value"); #endif } FKT_TerminalResponse (p->response, (USHORT)resp_len); PFREE (sim_toolkit_ind); if (SIM_IS_FLAG_CLEARED (CALL_ACTIVE) OR sim_data.status_time < THIRTY_SECONDS) TIMER_PSTART( sim_handle, SIM_TIMER, sim_data.status_time, sim_data.status_time); break; case STK_PROVIDE_LOCAL_INFO: /* * SIM toolkit request local information from the * SIM application. These informations are: * MCC, MNC, LAC, Cell Identity or IMEI. * SIM application sends this information with * a terminal response to the SIM toolkit. */ if(p_cmd EQ NULL) { TRACE_EVENT("p_cmd is NULL"); return; } switch (cmd_qual) { case QLF_PLOI_LOC_INFO: /* * request location information */ #ifdef _SIMULATION_ if (sim_data.location_info.c_loc NEQ 0) { memcpy (p->response, p_cmd, cmd_len); /* location information available */ memcpy (&p->response[cmd_len], &terminal_response_loci[5], 9); /* copy MCC, MNC & LAC */ memcpy (&p->response[cmd_len+ 9], &sim_data.location_info.loc[4], 5); /* copy cell identity */ p->response[cmd_len+14] = sim_data.cell_identity >> 8; p->response[cmd_len+15] = sim_data.cell_identity & 0xFF; p->response[cmd_len+ 6] = res_code[0]; resp_len = cmd_len + 16; #else if((cl_shrd_get_loc (&loc_info) EQ TRUE) AND (loc_info.service_mode NEQ NO_SERVICE)) { memcpy (p->response, p_cmd, cmd_len); /* location information available */ memcpy (&p->response[cmd_len], &terminal_response_loci[5], 9); /* copy from loc_info to response */ p->response[cmd_len+9] = loc_info.mcc[1] << 4; p->response[cmd_len+9] += loc_info.mcc[0]; p->response[cmd_len+10] = loc_info.mnc[2] << 4; p->response[cmd_len+10] += loc_info.mcc[2]; p->response[cmd_len+11] = loc_info.mnc[1] << 4; p->response[cmd_len+11] += loc_info.mnc[0]; p->response[cmd_len+12] = loc_info.lac >> 8; p->response[cmd_len+13] = loc_info.lac & 0xff; p->response[cmd_len+14] = loc_info.cell_id >> 8; p->response[cmd_len+15] = loc_info.cell_id & 0xFF; if ( loc_info.service_mode EQ LIMITED_SERVICE ) { p->response[cmd_len+ 6] = STK_RES_SUCC_LIMITED_SERVICE; } else { p->response[cmd_len+ 6] = res_code[0]; } resp_len = cmd_len + 16; #endif /* _SIMULATION_ */ } else { /* location information not available */ res_code[0] = STK_RES_BUSY_ME; res_code[1] = STK_RES_EXT_NO_SERVICE; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 2, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("PLI: local info not available"); #endif } sim_data.ext_sat_cmd = FALSE; break; case QLF_PLOI_IMEI: /* * request IMEI */ memcpy (p->response, p_cmd, cmd_len); memcpy (&p->response[cmd_len], &terminal_response_imei[5], 17); cl_get_imeisv(CL_IMEI_SIZE, &p->response[cmd_len + 9], CL_IMEI_GET_STORED_IMEI); for (i = (int)cmd_len + 8 + CL_IMEI_SIZE; i > (int)cmd_len + 9; i--) { /* place nibbles according to 4.08 */ p->response[i] = (p->response[i] & 0xf0) | (p->response[i - 1] & 0x0f); } /* i points to first IMEI octet, set 'type of identity' */ p->response[i] = (p->response[i] & 0xf0) | 0xA; p->response[cmd_len+8+CL_IMEI_SIZE] &= 0xF; p->response[cmd_len+ 6] = res_code[0]; resp_len = cmd_len + 17; sim_data.ext_sat_cmd = FALSE; break; case QLF_PLOI_NTW_MSR: /* * request network measurement results and BCCH list */ if ((sat_tp_sim_enabled[3] & SAT_TP4_PLI_NMR) EQ 0) { /* if not effective */ res_code[0] = STK_RES_ERR_NO_SUPPORT; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("PLI: NMR not supported"); #endif break; } memcpy (p->response, p_cmd, cmd_len); /* location information available */ memcpy (&p->response[cmd_len], &terminal_response_nmr[5], 9); if (get_network_meas (&p->response[cmd_len+9])) { /* * set result code */ #ifdef _SIMULATION_ p->response[cmd_len+ 6] = res_code[0]; resp_len = cmd_len + 25; #else if ((cl_shrd_get_loc (&loc_info) EQ TRUE) AND (loc_info.service_mode NEQ NO_SERVICE)) { if ( loc_info.service_mode EQ LIMITED_SERVICE ) { p->response[cmd_len+ 6] = STK_RES_SUCC_LIMITED_SERVICE; } else { p->response[cmd_len+ 6] = res_code[0]; } resp_len = cmd_len + 25; } else { res_code[0] = STK_RES_BUSY_ME; res_code[1] = STK_RES_EXT_NO_SERVICE; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 2, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("PLI: service mode not available"); #endif /* _SIMULATION_ */ } #endif /* _SIMULATION_ */ /* * Add BCCH list */ if (get_bcch_chan_list (&p->stk_data)) { /* * copy BCCH data list for answer */ p->response[resp_len] = 0x1D; /* BCCH channel flag */ p->response[resp_len + 1] = p->stk_data.stk_length; memcpy (&p->response[resp_len + 2], p->stk_data.stk_parameter, p->stk_data.stk_length); resp_len += (2+p->stk_data.stk_length); } else { /* location information not available */ res_code[0] = STK_RES_BUSY_ME; res_code[1] = STK_RES_EXT_NO_SERVICE; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 2, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("PLI: BCCH list not available"); #endif } } else { /* location information not available */ res_code[0] = STK_RES_BUSY_ME; res_code[1] = STK_RES_EXT_NO_SERVICE; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 2, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("PLI: measurement not available"); #endif } sim_data.ext_sat_cmd = FALSE; break; case QLF_PLOI_DTT: /* * Date, Time and Timezone */ if ((sim_data.stk_profile[7] & SAT_TP8_PLI_DTT) EQ 0) { /* if not effective */ res_code[0] = STK_RES_ERR_NO_SUPPORT; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("PLI: not supported in TP"); #endif break; } /* * Operations processed by MMI / MFW */ sim_data.ext_sat_cmd = TRUE; PSENDX (MMI, sim_toolkit_ind); break; case QLF_PLOI_LANG_SET: /* * Language Setting to be supported (to be processed by ACI) */ if ((sim_data.stk_profile[8] & SAT_TP9_PLI_LANG) EQ 0) { /* if not effective */ res_code[0] = STK_RES_ERR_NO_SUPPORT; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("language setting not supported"); #endif break; } /* * To be processed by ACI */ sim_data.sat_session = TRUE; sim_data.ext_sat_cmd = TRUE; PSENDX (MMI, sim_toolkit_ind); break; case QLF_PLOI_TIM_ADV: if ((sat_tp_sim_enabled[8] & SAT_TP9_PLI_TIMING_ADV) EQ 0) { res_code[0] = STK_RES_ERR_NO_SUPPORT; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("PLI: timing advance not supported"); #endif } else { memset (&tim_adv, 0, sizeof(T_TIM_ADV)); memcpy (p->response, p_cmd, cmd_len); memcpy (&p->response[cmd_len], &terminal_response_timingadv[5], 11); #ifdef _SIMULATION_ p->response[cmd_len+ 6] = res_code[0]; resp_len = cmd_len + 11; #else if(cl_shrd_get_tim_adv (&tim_adv) EQ TRUE) { p->response[cmd_len+9] = tim_adv.me_status; p->response[cmd_len+10] = tim_adv.tm_adv; /* * Set result code. */ p->response[cmd_len+ 6] = res_code[0]; resp_len = cmd_len + 11; } else { res_code[0] = STK_RES_BUSY_ME; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("PLI: Timing Advance not available"); #endif } #endif /* _SIMULATION_ */ } sim_data.ext_sat_cmd = FALSE; break; default: /* * no valid command qualifier */ res_code[0] = STK_RES_ERR_CMD_TYPE; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("PLI: type not understood"); #endif sim_data.ext_sat_cmd = FALSE; break; } if (!sim_data.ext_sat_cmd) /* may depend on Command Qualifier */ { FKT_TerminalResponse (p->response, (USHORT)resp_len); PFREE (sim_toolkit_ind); } break; case STK_REFRESH: /* * process SIM REFRESH according to command qualifier */ TRACE_EVENT("process SIM REFRESH according to command qualifier"); /* MALLOC area for CONTEXT SWITCH */ if ( sim_data.context_switch_ptr != NULL ) { TRACE_EVENT("ERROR!! context_switch_ptr should be NULL - freeing"); MFREE ( sim_data.context_switch_ptr ); sim_data.context_switch_ptr = NULL; } MALLOC (sim_data.context_switch_ptr, sizeof (T_CONTEXT_SWITCH)); memset ( sim_data.context_switch_ptr,0, sizeof (T_CONTEXT_SWITCH)); /* Set sig_ptr to handle required signal */ #ifdef TI_PS_FF_AT_P_CMD_CUST if (sim_data.cust_mode EQ 1) { /* Cust_Mode 1 operation setup*/ PALLOC(copy_sim_toolkit_ind,SIM_TOOLKIT_IND); memcpy(copy_sim_toolkit_ind,sim_toolkit_ind,sizeof(T_SIM_TOOLKIT_IND)); sim_data.context_switch_ptr->sig_ptr = copy_sim_toolkit_ind; } else { /*default operation setup*/ sim_data.context_switch_ptr->sig_ptr = sim_toolkit_ind; } #else /*default operation setup*/ sim_data.context_switch_ptr->sig_ptr = sim_toolkit_ind; #endif /* TI_PS_FF_AT_P_CMD_CUST */ /* Save decoding of original sim_toolkit_ind signal processed by stk_proactive_polling */ offset = (long)found_tag[2] - (long)sim_toolkit_ind; sim_data.context_switch_ptr->tag2 = (UBYTE *)(sim_data.context_switch_ptr->sig_ptr) + offset; sim_data.context_switch_ptr->fl_len = fl_len; offset = (long)p_cmd - (long)sim_toolkit_ind; sim_data.context_switch_ptr->p_cmd = (UBYTE *)(sim_data.context_switch_ptr->sig_ptr) + offset; sim_data.context_switch_ptr->cmd_len = cmd_len; sim_data.context_switch_ptr->res_code[0]=res_code[0]; sim_data.context_switch_ptr->res_code[1]=res_code[1]; #ifdef TI_PS_FF_AT_P_CMD_CUST /* functionality is depended on cust_mode */ if (sim_data.cust_mode EQ 1) { /* Cust_Mode 1 operation */ sim_data.user_confirmation_expected = TRUE; /*send Refresh command to MMI*/ PSENDX (MMI, sim_toolkit_ind); /*REFRESH COMMAND NOW PROCESSED IN stk_sim_refresh_user_res() */ /*note: stk_sim_refresh_user_res() will call process_sim_refresh() */ /* This routine will free sig_ptr, user must free the */ /* context_switch. */ /*Terminate Command */ break; } else { /* sim_data.cust_mode EQ 0 */ /* process default operation */ if ( process_sim_refresh(sim_data.context_switch_ptr) ) { /* processed a SIM_RESET. Special case - exit stk_proactive_polling()*/ MFREE(p); /* this thread has finished with the context switch so free it. */ MFREE (sim_data.context_switch_ptr); sim_data.context_switch_ptr = NULL; return; /* exit from stk_proactive_polling() */ } else { /* process_sim_refresh() frees signal sim_data.context_switch_ptr->sig_ptr */ /* this thread has finished with the context switch so free it. */ MFREE (sim_data.context_switch_ptr); sim_data.context_switch_ptr = NULL; } } #else /* sim_data.cust_mode EQ 0 */ /* process default operation */ if ( process_sim_refresh(sim_data.context_switch_ptr) ) { /* processed a SIM_RESET. Special case - exit stk_proactive_polling()*/ MFREE(p); /* this thread has finished with the context switch so free it. */ MFREE (sim_data.context_switch_ptr); sim_data.context_switch_ptr = NULL; return; /* exit from stk_proactive_polling() */ } else { /* process_sim_refresh() frees signal sim_data.context_switch_ptr->sig_ptr */ /* this thread has finished with the context switch so free it. */ MFREE (sim_data.context_switch_ptr); sim_data.context_switch_ptr = NULL; } #endif /* TI_PS_FF_AT_P_CMD_CUST */ break; //end of case STK_REFRESH #ifdef FF_SAT_E case STK_RECEIVE_DATA: if (stk_dti_bip_receive_data((T_sdu*)&sim_toolkit_ind->stk_cmd, res_code[0])) { /* * message contains TLV elements to display * so forward it to MMI */ sim_data.sat_session = TRUE; TRACE_EVENT("SEND receive data indication to MMI"); PSENDX (MMI, sim_toolkit_ind); TRACE_EVENT("receive data indication to MMI sent"); } else { PFREE (sim_toolkit_ind); } break; case STK_SEND_DATA: if (stk_dti_bip_send_data((T_sdu*)&sim_toolkit_ind->stk_cmd)) { /* * message contains TLV elements to display * so forward it to MMI */ sim_data.sat_session = TRUE; PSENDX (MMI, sim_toolkit_ind); } else { PFREE (sim_toolkit_ind); } break; #endif /* FF_SAT_E */ case STK_TIMER_MANAGEMENT: { UBYTE tag_tv[8] = {STK_TIMER_ID_TAG|STK_COMPREHENSION_REQUIRED, STK_TIMER_ID_LEN, 0, STK_TIMER_VALUE_TAG, STK_TIMER_VALUE_LEN, 0, 0 ,0}; tag_tv[2] = found_tag[2][0]; if ((unsigned)(i = (int)found_tag[2][0] - 1) >= MAX_SAT_TIMER) { /* invalid Timer identifier */ res_code[0] = STK_RES_ERR_CMD_DATA; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("stk_build_response No 17"); #endif } /* * Process TIMER MANAGEMENT according to command qualifier */ else switch (cmd_qual) { case 0: if (found_tag[3] EQ NULL) { res_code[0] = STK_RES_ERR_MISS_VALUE; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("TM: missing parameters"); #endif break; } /* translate timer value into unit of seconds */ tm_val = ((T_TIME)BCD2INT(found_tag[3][0]) * 60 + // hours (T_TIME)BCD2INT(found_tag[3][1])) * 60 + // minutes (T_TIME)BCD2INT(found_tag[3][2]); // seconds //TISH, patch for OMAPS00115011, 2007-02-12 //start if (tm_val==0) { res_code[0] = STK_RES_ERR_CMD_DATA; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); TRACE_ERROR("TR wrong tm value"); break; } //end sim_data.timer[i].hour = found_tag[3][0]; sim_data.timer[i].minute = found_tag[3][1]; sim_data.timer[i].second = found_tag[3][2]; TIMER_START (sim_handle, (USHORT)(i+1), (tm_val * 1000 - TIMER_LATENCY)); sim_data.timer[i].active = TRUE; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, tag_tv, 3); #ifdef _SIMULATION_ TRACE_EVENT("TM: set timer"); #endif break; case 1: case 2: if (sim_data.timer[i].active) { TIMER_STATUS (sim_handle, (USHORT)(i + 1), &tm_val); tm_val /= 1000; tag_tv[7] = INT2BCD((UBYTE)(tm_val % 60)); tm_val /= 60; tag_tv[6] = INT2BCD((UBYTE)(tm_val % 60)); tm_val /= 60; if (tm_val < 24) tag_tv[5] = INT2BCD((UBYTE)tm_val); else { // set maximum value tag_tv[7] = tag_tv[6] = 0x59; tag_tv[5] = 0x23; } if (cmd_qual EQ 1) /* timer to be stopped */ { TIMER_STOP (sim_handle, (USHORT)(i + 1)); sim_data.timer[i].active = FALSE; } resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, tag_tv, 8); #ifdef _SIMULATION_ TRACE_EVENT("TM: stop/query timer"); #endif } else { res_code[0] = STK_RES_BUSY_TIMER_STATE; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("TM: timer not running"); #endif } break; default: /* * not supported information request */ res_code[0] = STK_RES_ERR_CMD_TYPE; resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("TM: unknown qualifier"); #endif break; } FKT_TerminalResponse (p->response, (USHORT)resp_len); PFREE (sim_toolkit_ind); break; } default: result = FALSE; res_code[0] = STK_RES_ERR_CMD_TYPE; /* command type not understood */ /* * fall through */ case STK_POLLING_OFF: /* * SIM toolkit cancels the effect of a previous * POLL INTERVAL command. Polling of the SIM * toolkit is done now all thirty seconds with the * STATUS command, when in a call. */ if (result AND SIM_IS_FLAG_SET (PRO_ACTIVE_SIM)) { TRACE_EVENT("Idle Polling switched off"); sim_data.idle_polling = FALSE; /* there will not be a status command after this .so just force one status command to enable sleep */ startTimerPollOff = TRUE; if(SIM_IS_FLAG_SET(CALL_ACTIVE)) { /* SIM_TIMER will be restarted, during a call, for * presence detection */ sim_data.status_time = THIRTY_SECONDS; } else { /* timer value set to max, for with a '0', the timer would run for about one tick */ sim_data.status_time = 0xFFFFFFFF; TIMER_STOP (sim_handle, SIM_TIMER); } } case STK_MORE_TIME: /* * SIM toolkit needs more time. * SIM application sends terminal response with OK. */ resp_len = stk_build_response (p->response, p_cmd, cmd_len, res_code, 1, NULL, 0); #ifdef _SIMULATION_ TRACE_EVENT("MORE_TIME"); #endif FKT_TerminalResponse (p->response, (USHORT)resp_len); PFREE (sim_toolkit_ind); break; } } else { #ifdef _SIMULATION_ TRACE_EVENT("FKT_Fetch_NEQ_SIM_NO_ERROR"); #endif PFREE (sim_toolkit_ind); } MFREE (p); if (vsi_c_status (VSI_CALLER &in_queue, &out_queue) EQ VSI_OK) { if (in_queue > 0) break; /* break while */ } } /* END while */ /* * send end of SAT session indicator */ TRACE_FUNCTION ("stk_proactive_polling() send end of SAT session indicator"); if ((sim_data.term_resp_sent) AND (sim_data.sat_session)) { PALLOC (sim_toolkit_ind, SIM_TOOLKIT_IND); memset (sim_toolkit_ind, 0, sizeof (T_SIM_TOOLKIT_IND)); #ifdef _SIMULATION_ TRACE_EVENT("SAT session ended"); #endif sim_data.sat_session = FALSE; sim_data.term_resp_sent = FALSE; PSENDX (MMI, sim_toolkit_ind); } } TRACE_FUNCTION ("stk_proactive_polling() exited"); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_stop_all_sat_timers | +--------------------------------------------------------------------+ PURPOSE : Stop all timers started by TIMER MANAGEMENT, if running. Required when card is deactivated or reset. */ GLOBAL void stk_stop_all_sat_timers (void) { int i; for (i = 0; i < MAX_SAT_TIMER; i++) { if (sim_data.timer[i].active) { TIMER_STOP (sim_handle, (USHORT)(i + 1)); sim_data.timer[i].active = FALSE; } } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_start_timer_and_poll | +--------------------------------------------------------------------+ PURPOSE : Start STATUS timer and control SIM Toolkit Polling */ LOCAL void stk_start_timer_and_poll (void) { T_TIME t_val; /* * start status timer if SIM is inserted * for periodic status polling of SIM Toolkit */ if ((SIM_IS_FLAG_SET (PRO_ACTIVE_SIM) AND sim_data.idle_polling AND SIM_IS_FLAG_CLEARED (TEST_MODE_POLLING)) OR SIM_IS_FLAG_SET (CALL_ACTIVE)) { /* * Start Status Polling */ t_val = (SIM_IS_FLAG_SET (CALL_ACTIVE) AND sim_data.status_time > THIRTY_SECONDS)? THIRTY_SECONDS: sim_data.status_time; TIMER_PSTART (sim_handle, SIM_TIMER, t_val, t_val); } sim_data.chk_sat_avail = TRUE; // stk_proactive_polling(); } #ifdef FF_SAT_E /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_handle_ccd_error | +--------------------------------------------------------------------+ PURPOSE : Handle CCD error causes. */ LOCAL void stk_handle_ccd_error(UBYTE notOK, UBYTE* status, UBYTE* general_result, UBYTE* add_info_result) { UBYTE ccd_error; USHORT parameter_list[MAX_ERR_PAR]; TRACE_EVENT_P1("stk_handle_ccd_error(): %d", notOK); /* * handle errors in list */ memset (parameter_list, 0, sizeof(parameter_list)); ccd_error = ccd_getFirstError(CCDENT_SAT, parameter_list); if (notOK EQ ccdWarning) { while (ccd_error NEQ ERR_NO_MORE_ERROR) { switch (ccd_error) { case ERR_COMPREH_REQUIRED: /* * comprehension required */ TRACE_ERROR("CCD_WARNING=ERR_COMPREH_REQUIRED"); if (*status EQ SIM_CCD_OK) { *general_result = RSLT_UNKN_DATA; *add_info_result = ADD_NO_CAUSE; *status = SIM_CCD_RETURN; } break; case ERR_IE_NOT_EXPECTED: /* * unexpected element */ TRACE_ERROR("CCD_WARNING=ERR_IE_NOT_EXPECTED"); if (*status EQ SIM_CCD_OK) { *general_result = RSLT_PERF_PART_CMPR; *add_info_result = ADD_NO_CAUSE; } break; case ERR_MAND_ELEM_MISS: /* * mandatory elements missing */ TRACE_ERROR("CCD_WARNING=ERR_MAND_ELEM_MISS"); *general_result = RSLT_ERR_REQ_VAL; *add_info_result = ADD_NO_CAUSE; *status = SIM_CCD_RETURN; break; case ERR_MSG_LEN: TRACE_ERROR("CCD_WARNING=ERR_MSG_LEN (TC_509B)"); *general_result = RSLT_PERF_SUCCESS; *add_info_result = ADD_NO_CAUSE; *status = SIM_CCD_OK; break; default: TRACE_ERROR("CCD_WARNING ignored"); TRACE_EVENT_P1("ccd_error=0x%02X", ccd_error); break; } memset (parameter_list,0, sizeof(parameter_list)); ccd_error = ccd_getNextError (CCDENT_SAT, parameter_list); } } else /* ccdError */ { while (ccd_error NEQ ERR_NO_MORE_ERROR) { switch (ccd_error) { case ERR_COMPREH_REQUIRED: /* * comprehension required */ TRACE_ERROR("CCD_ERROR=ERR_COMPREH_REQUIRED"); if (*status EQ SIM_CCD_OK) { *general_result = RSLT_UNKN_DATA; *add_info_result = ADD_NO_CAUSE; *status = SIM_CCD_RETURN; } break; case ERR_IE_NOT_EXPECTED: /* * unexpected element */ TRACE_ERROR("CCD_ERROR=ERR_IE_NOT_EXPECTED"); if (*status EQ SIM_CCD_OK) { *general_result = RSLT_PERF_PART_CMPR; *add_info_result = ADD_NO_CAUSE; } break; case ERR_MAND_ELEM_MISS: /* * mandatory elements missing */ TRACE_ERROR("CCD_ERROR=ERR_MAND_ELEM_MISS"); *general_result = RSLT_ERR_REQ_VAL; *add_info_result = ADD_NO_CAUSE; *status = SIM_CCD_RETURN; break; case ERR_MSG_LEN: TRACE_ERROR("CCD_ERROR=ERR_MSG_LEN"); *general_result = RSLT_UNKN_DATA; *add_info_result = ADD_NO_CAUSE; *status = SIM_CCD_DISCARD; break; default: TRACE_ERROR("CCD_ERROR ignored"); TRACE_EVENT_P1("ccd_error=0x%02X", ccd_error); break; } memset (parameter_list,0, sizeof(parameter_list)); ccd_error = ccd_getNextError (CCDENT_SAT, parameter_list); } } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_bip_decode_stk_command | +--------------------------------------------------------------------+ PURPOSE : First step of decoding SEND DATA and RECEIVE DATA message. */ LOCAL void stk_bip_decode_stk_command(T_sdu* message, T_cmd_details* cmd_details, UBYTE* status, UBYTE* general_result, UBYTE* add_info_result) { UBYTE ccdRet; MCAST(stk_cmd, STK_CMD); memset(stk_cmd, 0, sizeof(T_STK_CMD)); /* * decode toolkit command */ ccdRet = ccd_decodeMsg (CCDENT_SAT, DOWNLINK, (T_MSGBUF *) message, (UBYTE *) _decodedMsg, STK_CMD); #ifdef _SIMULATION_ TRACE_EVENT_P1("ccdRet@bip_decode_stk_command: %d", ccdRet); #endif if ((stk_cmd->v_pas_cmd) AND (stk_cmd->pas_cmd.v_cmd_details)) { /* * store command details */ *cmd_details = stk_cmd->pas_cmd.cmd_details; if (ccdRet NEQ ccdOK) { /* * handle errors in list */ stk_handle_ccd_error(ccdRet, status, general_result, add_info_result); } if ((stk_cmd->pas_cmd.v_cmd_prms EQ FALSE) OR (stk_cmd->pas_cmd.v_dev_ids EQ FALSE)) { /* * no Channel Data (Length) element present or * no Device Identities element present * Error, required values are missing */ *general_result = RSLT_ERR_REQ_VAL; *add_info_result = ADD_NO_CAUSE; *status = SIM_CCD_RETURN; } if (*status EQ SIM_CCD_OK) { int i = 0; while (tbl_device_src_id[i]) { if (stk_cmd->pas_cmd.dev_ids.dest_dev EQ tbl_device_src_id[i]) break; i++; } if (tbl_device_src_id[i] EQ 0) { /* * device id not valid */ *general_result = RSLT_UNKN_DATA; *add_info_result = ADD_NO_CAUSE; *status = SIM_CCD_RETURN; } else if /* norm sim_data.bip_ch_id for 11.14/12.7 conform */ ((sim_data.bip_state EQ SIM_BIP_CLOSED) OR (stk_cmd->pas_cmd.dev_ids.dest_dev NEQ (sim_data.bip_ch_id | 0x020))) { /* * BIP error, Channel identifier not valid */ *general_result = RSLT_BEARIND_PERR; *add_info_result = ADD_BIP_CHANID_NT_VLD; *status = SIM_CCD_RETURN; } else { /* * store command parameters */ sim_data.bip_cmd_prms = stk_cmd->pas_cmd.cmd_prms; } } } else { /* * incomplete message */ *general_result = RSLT_ERR_REQ_VAL; *add_info_result = ADD_NO_CAUSE; *status = SIM_CCD_RETURN; /* * set Command Details object values to 0x00 */ cmd_details->cmd_nr = 0; cmd_details->cmd_typ = 0; cmd_details->cmd_qlf = 0; } } /* stk_bip_decode_stk_command */ /* +-----------------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_dti_send_data | +-----------------------------------------------------------------------------+ PURPOSE : Create and send a DTI Data primitive. */ LOCAL void stk_dti_send_data() { T_desc2* temp_desc1; /* * send DTI data primitive */ PALLOC_DESC2 (dti_data_ind, DTI2_DATA_IND); #ifdef _SIMULATION_ dti_data_ind->parameters.p_id = DTI_PID_UOS; dti_data_ind->parameters.st_lines.st_flow = DTI_FLOW_ON; dti_data_ind->parameters.st_lines.st_line_sa = DTI_SA_ON; dti_data_ind->parameters.st_lines.st_line_sb = DTI_SB_ON; dti_data_ind->parameters.st_lines.st_break_len = DTI_BREAK_OFF; #endif /* _SIMULATION_ */ switch(sim_data.con_type) { case SIM_CON_TYPE_UDP: MALLOC(temp_desc1, (USHORT)(sizeof(T_desc2) - 1 + sizeof(T_SRC_DES))); memcpy(temp_desc1->buffer, &sim_data.udp_parameters, sizeof(T_SRC_DES));/*lint !e419 Apparent data overrun for function*/ temp_desc1->len = sizeof(T_SRC_DES); temp_desc1->next = sim_data.data_to_send.first; sim_data.data_to_send.first = (ULONG)temp_desc1; sim_data.data_to_send.list_len+= temp_desc1->len; break; case SIM_CON_TYPE_IP: dti_data_ind->parameters.p_id = DTI_PID_IP; break; case SIM_CON_TYPE_SERIAL: dti_data_ind->parameters.st_lines.st_flow = DTI_FLOW_ON; dti_data_ind->parameters.st_lines.st_line_sa = DTI_SA_ON; dti_data_ind->parameters.st_lines.st_line_sb = DTI_SB_ON; dti_data_ind->parameters.st_lines.st_break_len = DTI_BREAK_OFF; break; } dti_data_ind->desc_list2 = sim_data.data_to_send; sim_data.data_to_send.first = (ULONG)NULL; sim_data.data_to_send.list_len = 0; dti_send_data(sim_data.hDTI, 0, 0, 0, dti_data_ind); } /* stk_dti_send_data() */ /* +-----------------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_bip_send_data_terminal_response | +-----------------------------------------------------------------------------+ PURPOSE : Send a Terminal Response message for a SEND DATA message. */ LOCAL void stk_bip_send_data_terminal_response(UBYTE general_result, UBYTE add_info_result) { T_sdu* temp_sdu; UBYTE ccdRet; /* * memory for encoded message */ MALLOC(temp_sdu, (USHORT)(sizeof(T_sdu) - 1 + MAX_STK_CMD)); temp_sdu->l_buf = MAX_STK_CMD << 3; temp_sdu->o_buf = 0; CCD_START; { MCAST(term_resp, TERM_RESP); memset(term_resp, 0, sizeof(T_TERM_RESP)); /* * set Command details */ term_resp->v_cmd_details = TRUE; term_resp->cmd_details = sim_data.bip_tx_cmd_details; /* * set set Device identities */ term_resp->v_dev_ids = TRUE; term_resp->dev_ids.src_dev = DEV_SRC_ME; term_resp->dev_ids.dest_dev = DEV_DST_SIM; /* * set Result */ term_resp->v_res = TRUE; term_resp->res.gen = general_result; switch(general_result) { case RSLT_ME_UNAB_PROC: case RSLT_NTW_UNAB_PROC: case RSLT_LABRWS_GENERIC: case RSLT_SS_ERR: case RSLT_SMS_ERR: case RSLT_USSD_ERR: case RSLT_CC_SIM_PRM: case RSLT_BEARIND_PERR: /* * one byte for additional information */ term_resp->res.v_add = TRUE; term_resp->res.add.l_add = 1 << 3; term_resp->res.add.o_add = 0; term_resp->res.add.b_add[0] = add_info_result; break; } /* * set Channel Data Length */ term_resp->v_chan_dat_lth = TRUE; if ((SIM_CLASS_E_BUFFER_SIZE - sim_data.data_to_send.list_len) > 255) { /* * more than 255 bytes are available in TX buffer */ term_resp->chan_dat_lth = 0xff; } else { term_resp->chan_dat_lth = SIM_CLASS_E_BUFFER_SIZE - sim_data.data_to_send.list_len; } /* * encode message */ ccdRet = ccd_codeMsg (CCDENT_SAT, UPLINK, (T_MSGBUF *) temp_sdu, (UBYTE *) _decodedMsg, TERM_RESP); } CCD_END; /* * send Terminal Response */ if (ccdRet NEQ ccdOK) { TRACE_EVENT_P1("SEND DATA: CCD Coding Error: %d",ccdRet ); } else { FKT_TerminalResponse (temp_sdu->buf, (USHORT)(temp_sdu->l_buf >> 3)); } MFREE(temp_sdu); } /* stk_bip_send_data_terminal_response() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_close_dti_connection | +--------------------------------------------------------------------+ PURPOSE : Close DTI connection. PARAMETER: The open parameter indicates if the DTI connection is still open or already closed. */ LOCAL void stk_close_dti_connection(UBYTE close) { #ifdef _SIMULATION_ TRACE_FUNCTION ("stk_close_dti_connection()"); #endif #ifdef _SIMULATION_ TRACE_EVENT_P1(" |___-->: sim_data.dti_connection_state=0x%02X", sim_data.dti_connection_state); #endif if (sim_data.dti_connection_state NEQ SIM_DTI_CONNECTION_CLOSED) { /* * close UDP connection */ if (sim_data.con_type EQ SIM_CON_TYPE_UDP) { /* * close currently used port */ if ((sim_data.dti_connection_state NEQ SIM_DTI_CONNECTION_BIND) AND (hCommUDP >= VSI_OK)) { PALLOC(udp_closeport_req, UDP_CLOSEPORT_REQ); udp_closeport_req->port = sim_data.udp_parameters.src_port[0]; udp_closeport_req->port = (udp_closeport_req->port << 8); udp_closeport_req->port+= sim_data.udp_parameters.src_port[1]; PSEND(hCommUDP, udp_closeport_req); } /* * release VSI channel */ if (hCommUDP >= VSI_OK) { vsi_c_close (VSI_CALLER hCommUDP); } hCommUDP = VSI_ERROR; } /* * disconnect BIP channel */ if (sim_data.bip_state EQ SIM_BIP_CONNECTED) { sim_data.bip_state = SIM_BIP_OPEN; /* * stop release timer */ if (sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) { if (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START) { #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: stopped"); #endif TIMER_STOP (sim_handle, SIM_BIP_TIMER); } sim_data.bip_timer_state = SIM_BIP_TIMER_DISCONNECTED; } } /* * close DTI connection */ sim_data.dti_connection_state = SIM_DTI_CONNECTION_CLOSED; if (close) { dti_close(sim_data.hDTI, 0, 0, 0, FALSE); } #ifdef _SIMULATION_ TRACE_EVENT_P1("stk_close_dti_connection: sim_data.dti_connection_state=0x%02X", sim_data.dti_connection_state); #endif } } /* stk_close_dti_connection() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_close_bip_channel | +--------------------------------------------------------------------+ PURPOSE : Close Bearer Independent Protocol Channel. */ LOCAL void stk_close_bip_channel(UBYTE general_result, UBYTE add_info_result) { T_desc2* temp_desc1; T_desc2* temp_desc2; if (sim_data.bip_state NEQ SIM_BIP_CLOSED) { /* * set BIP to close */ sim_data.bip_state = SIM_BIP_CLOSED; /* * stop release timer if used */ if (sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) { if (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START) { #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: stopped"); #endif TIMER_STOP (sim_handle, SIM_BIP_TIMER); } sim_data.bip_timer_state = SIM_BIP_TIMER_DISCONNECTED; } /* * send Terminal Response */ if (sim_data.bip_tx_state EQ SIM_BIP_TX_SEND) { stk_bip_send_data_terminal_response(general_result, add_info_result); /* * close channel is not triggered from a proactive_polling function call * so adjust timer and start polling */ stk_start_timer_and_poll(); } /* * release suspension */ sim_data.bip_suspend = FALSE; /* * release RX and TX buffer */ temp_desc1 = (T_desc2*)sim_data.data_to_send.first; while(temp_desc1) { temp_desc2 = temp_desc1; temp_desc1 = (T_desc2*)temp_desc1->next; MFREE(temp_desc2); } sim_data.data_to_send.first = (ULONG)NULL; sim_data.data_to_send.list_len = 0; sim_data.prev_data_to_send.first = (ULONG)NULL; sim_data.prev_data_to_send.list_len = 0; #ifdef _SIMULATION_ TRACE_EVENT("bip_tx_state = IDLE"); #endif sim_data.bip_tx_state = SIM_BIP_TX_IDLE; temp_desc1 = (T_desc2*)sim_data.received_data.first; while(temp_desc1) { temp_desc2 = temp_desc1; temp_desc1 = (T_desc2*)temp_desc1->next; MFREE(temp_desc2); } sim_data.received_data.first = (ULONG)NULL; sim_data.received_data.list_len = 0; sim_data.received_data_pos = 0; #ifdef _SIMULATION_ TRACE_EVENT("bip_rx_state = IDLE"); #endif sim_data.bip_rx_state = SIM_BIP_RX_IDLE; } } /* stk_close_bip_channel() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_dti_inform_mmi | +--------------------------------------------------------------------+ PURPOSE : Informs MMI if the requested actions have been done. */ LOCAL void stk_dti_inform_mmi (UBYTE dti_conn_req, UBYTE bip_conn_req ) { UBYTE dti_conn_done; UBYTE bip_conn_done; #if _SIMULATION_ TRACE_FUNCTION ("stk_dti_inform_mmi()"); #endif /* * set stutus */ dti_conn_done = 0; bip_conn_done = 0; if (sim_data.bip_state EQ SIM_BIP_CLOSED) { bip_conn_done |= SIM_BIP_CLOSE_CHANNEL; } else { bip_conn_done |= SIM_BIP_OPEN_CHANNEL; /* * Only if BIP channel not closed, deal with its suspension state */ if (sim_data.bip_suspend) { bip_conn_done |= SIM_BIP_CHANNEL_SUSPENDED; } else { bip_conn_done |= SIM_BIP_CHANNEL_RESUMED; } } if (sim_data.dti_connection_state EQ SIM_DTI_CONNECTION_OPEN) { dti_conn_done = SIM_DTI_CONNECT; } if (sim_data.dti_connection_state EQ SIM_DTI_CONNECTION_CLOSED) { dti_conn_done = SIM_DTI_DISCONNECT; } /* * inform MMI */ if ( /* reguirements REALLY fullfilled in code, then confirm or indicate */ /* else no reaction at all !! */ (((bip_conn_req & bip_conn_done) EQ bip_conn_req) OR (bip_conn_req EQ SIM_BIP_UNKNOWN)) AND ((dti_conn_req EQ dti_conn_done)OR (dti_conn_req EQ SIM_DTI_UNKNOWN)) AND (~(UCHAR)((dti_conn_req EQ SIM_DTI_UNKNOWN) AND (bip_conn_req EQ SIM_BIP_UNKNOWN))) ) { if (sim_data.sim_dti_req) { /* * send DTI confirm primitive */ PALLOC(sim_dti_cnf, SIM_DTI_CNF); sim_dti_cnf->link_id = sim_data.sim_dti_req->link_id; sim_dti_cnf->dti_conn = dti_conn_done; PSEND(hCommMMI, sim_dti_cnf); /* * free request primitive */ PFREE(sim_data.sim_dti_req); sim_data.sim_dti_req = NULL; } else if (sim_data.sim_bip_req) { /* * send BIP confirm primitive */ PALLOC(sim_bip_cnf, SIM_BIP_CNF); sim_bip_cnf->bip_ch_id = sim_data.sim_bip_req->bip_ch_id; sim_bip_cnf->bip_conn = bip_conn_done; PSEND(hCommMMI, sim_bip_cnf); /* * free request primitive */ PFREE(sim_data.sim_bip_req); sim_data.sim_bip_req = NULL; } else { /* * send indication primitive */ PALLOC(sim_dti_bip_ind, SIM_DTI_BIP_IND); sim_dti_bip_ind->link_id = sim_data.link_id; sim_dti_bip_ind->dti_conn = dti_conn_done; sim_dti_bip_ind->bip_ch_id = sim_data.bip_ch_id; sim_dti_bip_ind->bip_conn = bip_conn_done; PSEND(hCommMMI, sim_dti_bip_ind); } } /* and if (requirements fullfilled) */ } /* stk_dti_inform_mmi() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_dti_connection_opened | +--------------------------------------------------------------------+ PURPOSE : Handle CONNECTION OPENED signal from DTILIB. */ GLOBAL void stk_dti_connection_opened (void) { TRACE_FUNCTION ("stk_dti_connection_opened()"); switch(sim_data.dti_connection_state) { case SIM_DTI_CONNECTION_SETUP: sim_data.dti_connection_state = SIM_DTI_CONNECTION_OPEN; /* * send confirm primitive */ stk_dti_inform_mmi(sim_data.sim_dti_req->dti_conn, (UBYTE) SIM_BIP_UNKNOWN); /* fall through */ case SIM_DTI_CONNECTION_OPEN: /* * connect BIP with DTI */ if (sim_data.bip_state EQ SIM_BIP_OPEN) { sim_data.bip_state = SIM_BIP_CONNECTED; if (sim_data.bip_release_time EQ SIM_NO_AUTO_RELEASE) { sim_data.bip_timer_state = SIM_BIP_TIMER_NOT_USED; } else if (sim_data.bip_suspend) { sim_data.bip_timer_state = SIM_BIP_TIMER_SUSPENDED; } else { sim_data.bip_timer_state = SIM_BIP_TIMER_STOPPED; } } break; default: /* * wrong state * so close DTI connection * and inform MMI */ TRACE_ERROR("DTI_CONNECTION_OPENED in wrong state"); stk_close_dti_connection(TRUE); stk_dti_inform_mmi(SIM_DTI_DISCONNECT, (UBYTE) SIM_BIP_UNKNOWN); break; } /* * reset RX, TX and timer */ sim_data.dti_rx_state = SIM_DTI_RX_IDLE; sim_data.dti_tx_state = SIM_DTI_TX_IDLE; #if 0 /*###jk:OK?*/ if (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START) { sim_data.bip_timer_state = SIM_BIP_TIMER_STOPPED; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: stopped"); #endif TIMER_STOP (sim_handle, SIM_BIP_TIMER); } /* * update timer and DTI states */ if ((sim_data.bip_state EQ SIM_BIP_CONNECTED) AND (sim_data.bip_rx_state EQ SIM_BIP_RX_IDLE)) { /* * start reception */ sim_data.dti_rx_state = SIM_DTI_RX_READY; dti_start(sim_data.hDTI, 0, 0, 0); /* * start timer */ if ((sim_data.bip_timer_state EQ SIM_BIP_TIMER_STOPPED) AND (sim_data.bip_tx_state EQ SIM_BIP_TX_IDLE) ) { /* * no data trafic on the BIP channel, * so use the timer */ sim_data.bip_timer_state = SIM_BIP_TIMER_START; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: start in stk_dti_connection_opened()"); #endif TIMER_START (sim_handle, SIM_BIP_TIMER, sim_data.bip_release_time); } } #endif /*###jk:OK?*/ } /* stk_dti_connection_opened() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_dti_connection_closed | +--------------------------------------------------------------------+ PURPOSE : Handle CONNECTION CLOSED signal from DTILIB. */ GLOBAL void stk_dti_connection_closed (void) { TRACE_FUNCTION ("stk_dti_connection_closed()"); /* * close DTI connection */ stk_close_dti_connection(FALSE); /* * inform MMI about disconnection */ stk_dti_inform_mmi(SIM_DTI_DISCONNECT, (UBYTE) SIM_BIP_UNKNOWN); } /* stk_dti_connection_closed() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_dti_data_received | +--------------------------------------------------------------------+ PURPOSE : Deal with incomming DTI data primitives. */ GLOBAL void stk_dti_data_received (T_DTI2_DATA_IND* dti_data_ind) { UBYTE ccdRet; UBYTE dummy[4]; T_sdu* temp_sdu; T_desc2* temp_desc1; T_desc2* temp_desc2; TRACE_FUNCTION ("stk_dti_data_received()"); #ifdef _SIMULATION_ /* * copy bytes of T_SRC_DES struct in extra descriptor * this is a requirement of the DTI communication with UDP, but it should * not have any side affects in case of communication with other entities */ if ((dti_data_ind->desc_list2.first NEQ (ULONG)NULL) AND (dti_data_ind->desc_list2.list_len >= sizeof(T_SRC_DES))) { T_desc2 *old_desc, *addr_desc, *test_desc, *next_desc; USHORT i, j; old_desc = (T_desc2 *)dti_data_ind->desc_list2.first; /* * build the T_SRC_DES for IP-addresses and ports */ MALLOC(addr_desc, (USHORT)(sizeof(T_desc2) - 1 + sizeof(T_SRC_DES))); addr_desc->len = sizeof(T_SRC_DES); j = 0; for(i=0; i < addr_desc->len; i++) { while(j >= old_desc->len) { next_desc = (T_desc2*)old_desc->next; MFREE(old_desc); old_desc = next_desc; j = 0; } addr_desc->buffer[i] = old_desc->buffer[j]; j++; } /* * Build the desc for the data */ if (j < old_desc->len) { MALLOC(test_desc, (USHORT)(sizeof(T_desc2) - 1 + old_desc->len - j)); test_desc->len = old_desc->len - j; test_desc->next = old_desc->next; for(i=0; i < test_desc->len; i++) { test_desc->buffer[i] = old_desc->buffer[j]; j++; } } else { test_desc = (T_desc2*)old_desc->next; } MFREE(old_desc); dti_data_ind->desc_list2.first = (ULONG)addr_desc; addr_desc->next = (ULONG)test_desc; } #endif /* _SIMULATION_ */ /* * take data */ temp_desc1 = (T_desc2*)dti_data_ind->desc_list2.first; /* * free primitive */ PFREE(dti_data_ind); /* * */ switch(sim_data.con_type) { /* --67 asd; ###jk test error for image*/ case SIM_CON_TYPE_UDP: /* * free first descriptor */ temp_desc2 = temp_desc1; if (temp_desc1) { temp_desc1 = (T_desc2*)temp_desc1->next; } MFREE(temp_desc2); /* fall through */ case SIM_CON_TYPE_IP: /* * store data */ if (sim_data.received_data.first EQ (ULONG)NULL) { sim_data.received_data.first = (ULONG)temp_desc1; } else { /* * error * free received data */ TRACE_ERROR("DTI data received, but still data in RX buffer"); while(temp_desc1) { temp_desc2 = temp_desc1; temp_desc1 = (T_desc2*)temp_desc1->next; MFREE(temp_desc2); } temp_desc1 = NULL; } break; case SIM_CON_TYPE_SERIAL: /* * store data */ if (sim_data.received_data.first EQ (ULONG)NULL) { sim_data.received_data.first = (ULONG)temp_desc1; } else { /* * error, but concatinate data */ TRACE_ERROR("DTI data received, but still data in RX buffer"); /* * find last descriptor */ temp_desc2 = (T_desc2*)sim_data.received_data.first; while(temp_desc2->next NEQ (ULONG)NULL) { temp_desc2 = (T_desc2*)temp_desc2->next; } temp_desc2->next = (ULONG)temp_desc1; } break; } /* * update list length */ while(temp_desc1) { sim_data.received_data.list_len+= temp_desc1->len; temp_desc1 = (T_desc2*)temp_desc1->next; } if (sim_data.received_data.list_len) { /* * change state of BIP RX and stop timer */ #ifdef _SIMULATION_ TRACE_EVENT("bip_rx_state = DATA"); #endif sim_data.bip_rx_state = SIM_BIP_RX_DATA; if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START) ) { sim_data.bip_timer_state = SIM_BIP_TIMER_STOPPED; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: stopped"); #endif TIMER_STOP (sim_handle, SIM_BIP_TIMER); } /* * stop reception */ sim_data.dti_rx_state = SIM_DTI_RX_IDLE; dti_stop(sim_data.hDTI, 0, 0, 0); /* * inform SIM card */ if (sim_data.event_data_avail EQ SIM_EVENT_ENABLE) { CCD_START; { MCAST(env_cmd, ENV_CMD); memset(env_cmd, 0, sizeof(T_ENV_CMD)); /* * Event Download Command */ env_cmd->v_evd_cmd = TRUE; /* * Event List */ env_cmd->evd_cmd.v_ev_list = TRUE; env_cmd->evd_cmd.ev_list.c_event = 1; env_cmd->evd_cmd.ev_list.event[0] = EVENT_DATA_AVAIL; /* * Device Identities */ env_cmd->evd_cmd.v_dev_ids = TRUE; env_cmd->evd_cmd.dev_ids.src_dev = DEV_SRC_ME; env_cmd->evd_cmd.dev_ids.dest_dev = DEV_DST_SIM; /* * Channel Satus */ env_cmd->evd_cmd.v_chan_stat = TRUE; env_cmd->evd_cmd.chan_stat.chan_id = sim_data.bip_ch_id & 0x07; env_cmd->evd_cmd.chan_stat.chan_stat_inf1 = 0; env_cmd->evd_cmd.chan_stat.chan_stat_link = LINK_ESTABL; env_cmd->evd_cmd.chan_stat.chan_stat_inf2 = NO_FURTH_INFO; /* * Channel Data Length */ env_cmd->evd_cmd.v_chan_dat_lth = TRUE; if (sim_data.received_data.list_len > 255) { /* * more than 255 bytes are available in RX buffer */ env_cmd->evd_cmd.chan_dat_lth = 0xff; } else { env_cmd->evd_cmd.chan_dat_lth = (UBYTE)sim_data.received_data.list_len; } /* * encode message */ MALLOC(temp_sdu, (USHORT)(sizeof(T_sdu) - 1 + MAX_STK_CMD)); temp_sdu->l_buf = MAX_STK_CMD << 3; temp_sdu->o_buf = 0; ccdRet = ccd_codeMsg (CCDENT_SAT, UPLINK, (T_MSGBUF *) temp_sdu, (UBYTE *) _decodedMsg, ENV_CMD); } CCD_END; if ( ccdRet NEQ ccdOK ) { TRACE_EVENT_P1("Data Available: CCD Coding Error: %d",ccdRet ); } else { FKT_Envelope (dummy, temp_sdu->buf, (USHORT)(temp_sdu->l_buf >> 3), 0); /* * data received is not triggered from a proactive_polling * function call, so adjust timer and start polling */ stk_start_timer_and_poll(); } MFREE(temp_sdu); } } } /* stk_dti_data_received() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_dti_tx_buffer_full | +--------------------------------------------------------------------+ PURPOSE : Handle TX BUFFER FULL signal from DTILIB. */ GLOBAL void stk_dti_tx_buffer_full (void) { TRACE_FUNCTION ("stk_dti_tx_buffer_full()"); /* * set new DTI state */ sim_data.dti_tx_state = SIM_DTI_TX_IDLE; } /* stk_dti_tx_buffer_full() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_dti_tx_buffer_ready | +--------------------------------------------------------------------+ PURPOSE : Handle TX BUFFER READY signal from DTILIB. */ GLOBAL void stk_dti_tx_buffer_ready (void) { TRACE_FUNCTION ("stk_dti_tx_buffer_ready()"); /* * set new DTI state */ sim_data.dti_tx_state = SIM_DTI_TX_READY; /* * send confirm primitive to MMI: out of here; actually as the response for * SIM_BIP_CONFIG_REQ */ if ((sim_data.sim_bip_config_req) AND (sim_data.dti_connection_state EQ SIM_DTI_CONNECTION_SETUP)) { PALLOC(sim_bip_config_cnf, SIM_BIP_CONFIG_CNF); PSEND(hCommMMI, sim_bip_config_cnf); /* primitive no longer needed.. */ /* and so avoid the second confirm in stk_udp_bind_cnf() */ PFREE(sim_data.sim_bip_config_req); sim_data.sim_bip_config_req = NULL; /* * set the open state: the connection is now truly opened */ sim_data.dti_connection_state = SIM_DTI_CONNECTION_OPEN; } /* * send data */ if (sim_data.bip_tx_state EQ SIM_BIP_TX_SEND) { /* * set new BIP state */ #ifdef _SIMULATION_ TRACE_EVENT("bip_tx_state = IDLE"); #endif sim_data.bip_tx_state = SIM_BIP_TX_IDLE; /* * send DTI data primitive */ stk_dti_send_data(); /* * send Terminal Response */ stk_bip_send_data_terminal_response(sim_data.bip_general_result, sim_data.bip_add_info_result); /* * buffer ready is not triggered from a proactive_polling function call * so adjust timer and start polling */ stk_start_timer_and_poll(); /* * (re)start release timer */ if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_rx_state EQ SIM_BIP_RX_IDLE) AND ((sim_data.bip_timer_state EQ SIM_BIP_TIMER_STOPPED) OR (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START))) { sim_data.bip_timer_state = SIM_BIP_TIMER_START; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: start in stk_dti_tx_buffer_ready()"); #endif TIMER_START (sim_handle, SIM_BIP_TIMER, sim_data.bip_release_time); } } } /* stk_dti_tx_buffer_ready() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_dti_bip_send_data | +--------------------------------------------------------------------+ PURPOSE : Handle SEND DATA message from SIM card. */ GLOBAL UBYTE stk_dti_bip_send_data (T_sdu* message) { UBYTE ccdRet; UBYTE func_ret; UBYTE general_result; UBYTE add_info_result; UBYTE status; T_desc2* temp_desc1; T_desc2* temp_desc2; USHORT temp_pos; USHORT temp_len; TRACE_FUNCTION ("stk_dti_bip_send_data()"); /* * initialize value; */ ccdRet = ccdOK; func_ret = FALSE; general_result = RSLT_PERF_SUCCESS; add_info_result = ADD_NO_CAUSE; status = SIM_CCD_OK; CCD_START; /* * decode SIM Toolkit Command */ stk_bip_decode_stk_command(message, &sim_data.bip_tx_cmd_details, &status, &general_result, &add_info_result); /* * decode SEND DATA message */ if (status EQ SIM_CCD_OK) { MCAST(send_data, SEND_DATA); memset(send_data, 0, sizeof(T_SEND_DATA)); /* * decode SEND DATA message */ ccdRet = ccd_decodeMsg (CCDENT_SAT, DOWNLINK, (T_MSGBUF *) &sim_data.bip_cmd_prms, (UBYTE *) _decodedMsg, SEND_DATA); if (ccdRet NEQ ccdOK) { /* * handle errors in list */ stk_handle_ccd_error(ccdRet, &status, &general_result, &add_info_result); } if (send_data->v_chan_data EQ FALSE) { /* * no Channel Data element present * Error, required values are missing */ general_result = RSLT_ERR_REQ_VAL; add_info_result = ADD_NO_CAUSE; status = SIM_CCD_RETURN; } if (status EQ SIM_CCD_OK) { if (sim_data.bip_suspend) { /* * channel suspended * ME currently unable to process command */ general_result = sim_data.bip_general_result; add_info_result = sim_data.bip_add_info_result; status = SIM_CCD_RETURN; } else if ((SIM_CLASS_E_BUFFER_SIZE - sim_data.data_to_send.list_len) < send_data->chan_data.c_ch_dat_str) { /* * not enough space in tx buffer * BIP error */ general_result = RSLT_BEARIND_PERR; add_info_result = ADD_BIP_BUF_SIZ_NAVAIL; status = SIM_CCD_RETURN; } else { /* * concatenate Channel data */ sim_data.prev_data_to_send = sim_data.data_to_send; if (sim_data.data_to_send.first NEQ (ULONG)NULL) { /* * find last descriptor */ temp_desc1 = (T_desc2*)sim_data.data_to_send.first; while(temp_desc1->next NEQ (ULONG)NULL) { temp_desc1 = (T_desc2*)temp_desc1->next; } } else if (send_data->chan_data.c_ch_dat_str) { /* * allocate a new descriptor */ MALLOC(temp_desc1, (USHORT)(sizeof(T_desc2) - 1 + SIM_BIP_TX_DESC_SIZE)); temp_desc1->next = (ULONG)NULL; temp_desc1->offset= 0; /*###jk:OK*/ temp_desc1->len = 0; temp_desc1->size= 0; /*###jk:OK*/ sim_data.data_to_send.first = (ULONG)temp_desc1; sim_data.data_to_send.list_len = 0; } temp_pos = 0; while(temp_pos < send_data->chan_data.c_ch_dat_str) { if (temp_desc1->len >= SIM_BIP_TX_DESC_SIZE) /*lint !e644 temp_desc1 may not have been initialized*/ { /* * allocate new desriptor */ temp_desc2 = temp_desc1; MALLOC(temp_desc1, (USHORT)(sizeof(T_desc2) - 1 + SIM_BIP_TX_DESC_SIZE)); temp_desc1->next = (ULONG)NULL; temp_desc1->offset = 0; /*###jk:OK*/ temp_desc1->len = 0; temp_desc1->size = 0; /*###jk:OK*/ temp_desc2->next = (ULONG)temp_desc1; } /* * calculate length */ temp_len = send_data->chan_data.c_ch_dat_str - temp_pos; if (temp_len > (SIM_BIP_TX_DESC_SIZE - temp_desc1->len)) { temp_len = SIM_BIP_TX_DESC_SIZE - temp_desc1->len; TRACE_EVENT("sdbsd_5: if (temp_desc1->len >= SIM_BIP_TX_DESC_SIZE)"); /*###jk:tbd*/ TRACE_EVENT_P1("sdbsd_5: temp_len = %d", temp_len); /*###jk:tbd*/ } /* * copy data */ memcpy(&temp_desc1->buffer[temp_desc1->len], &send_data->chan_data.ch_dat_str[temp_pos], temp_len); temp_pos += temp_len; temp_desc1->len += temp_len; temp_desc1->size += temp_len; /*###jk:OK?*/ sim_data.data_to_send.list_len+= temp_len; } } /* * process SEND DATA message */ if (status EQ SIM_CCD_OK) { /* * if alpha identifier or icon identifier is present then * forward message to MMI */ if ((send_data->v_alpha_id) OR (send_data->v_icon)) { func_ret = TRUE; } /* * check for immediate/store bit */ if (sim_data.bip_tx_cmd_details.cmd_qlf & SIM_QLF_SEND_DATA_1) { /* * send data immediately */ if (sim_data.bip_state EQ SIM_BIP_CONNECTED) { /* * DTI connected */ if (sim_data.dti_tx_state EQ SIM_DTI_TX_READY) { /* * send DTI data primitive */ #ifdef _SIMULATION_ TRACE_EVENT("bip_tx_state = IDLE"); #endif sim_data.bip_tx_state = SIM_BIP_TX_IDLE; status = SIM_CCD_RETURN; stk_dti_send_data(); } else { TRACE_EVENT("stbsd_8: else (sim_data.dti_tx_state EQ SIM_DTI_TX_READY)"); /*###jk:tbd*/ /* * start release timer */ #ifdef _SIMULATION_ TRACE_EVENT("bip_tx_state = SEND"); #endif sim_data.bip_tx_state = SIM_BIP_TX_SEND; status = SIM_CCD_DISCARD; if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START) ) { sim_data.bip_timer_state = SIM_BIP_TIMER_STOPPED; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: stopped"); #endif TIMER_STOP (sim_handle, SIM_BIP_TIMER); } } /* * (re)start release timer */ if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_rx_state EQ SIM_BIP_RX_IDLE) AND (sim_data.bip_tx_state EQ SIM_BIP_TX_IDLE) AND ((sim_data.bip_timer_state EQ SIM_BIP_TIMER_STOPPED) OR (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START))) { sim_data.bip_timer_state = SIM_BIP_TIMER_START; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: start in stk_dti_bip_send_data(..)"); #endif TIMER_START (sim_handle, SIM_BIP_TIMER, sim_data.bip_release_time); } } else { TRACE_EVENT("stbsd_7: else (sim_data.bip_state EQ SIM_BIP_CONNECTED)"); /*###jk:tbd*/ /* * wait for DTI connection */ #ifdef _SIMULATION_ TRACE_EVENT("bip_tx_state = SEND"); #endif sim_data.bip_tx_state = SIM_BIP_TX_SEND; status = SIM_CCD_DISCARD; if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START) ) { sim_data.bip_timer_state = SIM_BIP_TIMER_STOPPED; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: stopped"); #endif TIMER_STOP (sim_handle, SIM_BIP_TIMER); } if (sim_data.dti_connection_state EQ SIM_DTI_CONNECTION_CLOSED) { /* * on demand link establishment * so forward message to MMI */ func_ret = TRUE; } } } else { /* * store data */ TRACE_EVENT("bip_tx_state = STORE"); sim_data.bip_tx_state = SIM_BIP_TX_STORE; status = SIM_CCD_RETURN; /* * stop release timer if used */ if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START) ) { sim_data.bip_timer_state = SIM_BIP_TIMER_STOPPED; TRACE_EVENT("SIM_BIP_TIMER: stopped"); TIMER_STOP (sim_handle, SIM_BIP_TIMER); } } } } } /* if (status EQ SIM_CCD_OK) */ CCD_END; /* * send TERMINAL RESPONSE message */ if (status EQ SIM_CCD_RETURN) { stk_bip_send_data_terminal_response(general_result, add_info_result); } else { /* * store result codes */ sim_data.bip_general_result = general_result; sim_data.bip_add_info_result = add_info_result; } /* * send return value */ return func_ret; } /* stk_dti_bip_send_data() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_STK | | STATE : code ROUTINE : stk_dti_bip_receive_data | +--------------------------------------------------------------------+ PURPOSE : Handle RECEIVE DATA message from SIM card. */ LOCAL UBYTE stk_dti_bip_receive_data (T_sdu* message, UBYTE result_code) { UBYTE ccdRet; UBYTE func_ret; UBYTE general_result; UBYTE add_info_result; UBYTE status; UBYTE chan_dat_lth; T_desc2* temp_desc1; T_desc2* temp_desc2; T_sdu* temp_sdu; USHORT temp_pos; USHORT temp_len; /* * initialize value; */ ccdRet = ccdOK; func_ret = FALSE; general_result = RSLT_PERF_SUCCESS; add_info_result = ADD_NO_CAUSE; status = SIM_CCD_OK; chan_dat_lth = 0; /* jk: initialized because of LINT error */ CCD_START; /* * decode SIM Toolkit Command */ stk_bip_decode_stk_command(message, &sim_data.bip_rx_cmd_details, &status, &general_result, &add_info_result); /* * decode RECEIVE DATA message */ if (status EQ SIM_CCD_OK) { MCAST(receive_data, RECEIVE_DATA); memset(receive_data, 0, sizeof(T_RECEIVE_DATA)); ccdRet = ccd_decodeMsg (CCDENT_SAT, DOWNLINK, (T_MSGBUF *) &sim_data.bip_cmd_prms, (UBYTE *) _decodedMsg, RECEIVE_DATA); #ifdef _SIMULATION_ TRACE_EVENT_P1("ccdRet@dti_bip_receive_data: %d", ccdRet); #endif if (ccdRet NEQ ccdOK) { /* * handle errors in list */ stk_handle_ccd_error(ccdRet, &status, &general_result, &add_info_result); } if (receive_data->v_chan_dat_lth EQ FALSE) { /* * no Channel Data Length element present * Error, required values are missing */ general_result = RSLT_ERR_REQ_VAL; add_info_result = ADD_NO_CAUSE; status = SIM_CCD_RETURN; } /* * process RECEIVE DATA message */ if (status EQ SIM_CCD_OK) { /* * if alpha identifier or icon identifier is present then * forward message to MMI */ if ((receive_data->v_alpha_id) OR (receive_data->v_icon)) { func_ret = TRUE; } if (sim_data.received_data.list_len < receive_data->chan_dat_lth) { /* * can not fill the complete buffer */ general_result = RSLT_PERF_MISS_INFO; add_info_result = ADD_NO_CAUSE; } status = SIM_CCD_RETURN; /* * store Channel Data Length */ chan_dat_lth = receive_data->chan_dat_lth; } } CCD_END; /* * send TERMINAL RESPONSE message */ if (status EQ SIM_CCD_RETURN) { CCD_START; { MCAST(term_resp, TERM_RESP); memset(term_resp, 0, sizeof(T_TERM_RESP)); /* * set Command details */ term_resp->v_cmd_details = TRUE; term_resp->cmd_details = sim_data.bip_rx_cmd_details; /* * set set Device identities */ term_resp->v_dev_ids = TRUE; term_resp->dev_ids.src_dev = DEV_SRC_ME; term_resp->dev_ids.dest_dev = DEV_DST_SIM; /* * set Result */ term_resp->v_res = TRUE; term_resp->res.gen = general_result; switch (general_result) { case RSLT_ME_UNAB_PROC: case RSLT_NTW_UNAB_PROC: case RSLT_LABRWS_GENERIC: case RSLT_SS_ERR: case RSLT_SMS_ERR: case RSLT_USSD_ERR: case RSLT_CC_SIM_PRM: /* * one byte for additional information */ term_resp->res.v_add = TRUE; term_resp->res.add.l_add = 1 << 3; term_resp->res.add.o_add = 0; term_resp->res.add.b_add[0] = add_info_result; break; case RSLT_BEARIND_PERR: /* * one byte for additional information */ term_resp->res.v_add = TRUE; term_resp->res.add.l_add = 1 << 3; term_resp->res.add.o_add = 0; term_resp->res.add.b_add[0] = add_info_result-1; break; default: if (result_code) term_resp->res.gen = RSLT_PERF_PART_CMPR; break; } /* * set Channel Data */ term_resp->v_chan_data = TRUE; switch (general_result) { case RSLT_PERF_SUCCESS: case RSLT_PERF_PART_CMPR: case RSLT_PERF_MISS_INFO: case RSLT_PERF_MDFY_SIM: case RSLT_PERF_MDFIED: /* * calculate Channel Data String length */ term_resp->chan_data.c_ch_dat_str = SIM_TERM_RESP_MAX_CHANNEL_DATA; if (sim_data.received_data.list_len < term_resp->chan_data.c_ch_dat_str) { term_resp->chan_data.c_ch_dat_str = (UBYTE)sim_data.received_data.list_len; } if (chan_dat_lth < term_resp->chan_data.c_ch_dat_str) { term_resp->chan_data.c_ch_dat_str = chan_dat_lth; } /* * copy data */ temp_desc1 = (T_desc2*)sim_data.received_data.first; temp_pos = 0; while (temp_pos < term_resp->chan_data.c_ch_dat_str) { /* * calculate length */ temp_len = term_resp->chan_data.c_ch_dat_str - temp_pos; if (temp_len > (temp_desc1->len - sim_data.received_data_pos)) { temp_len = temp_desc1->len - sim_data.received_data_pos; } /* * copy data */ memcpy(&term_resp->chan_data.ch_dat_str[temp_pos], &temp_desc1->buffer[sim_data.received_data_pos], temp_len); /* * updata length and position values and descriptors */ temp_pos += temp_len; sim_data.received_data_pos += temp_len; sim_data.received_data.list_len-= temp_len; if (sim_data.received_data_pos >= temp_desc1->len) { temp_desc2 = temp_desc1; temp_desc1 = (T_desc2*)temp_desc1->next; sim_data.received_data_pos = 0; sim_data.received_data.first = (ULONG)temp_desc1; MFREE(temp_desc2); } } break; case RSLT_BEARIND_PERR: case RSLT_UNKN_DATA: term_resp->v_chan_data = FALSE; term_resp->chan_data.c_ch_dat_str = 0; break; default: /* * if an error is occured then do not provide data */ term_resp->chan_data.c_ch_dat_str = 0; break; } switch (general_result) { case RSLT_BEARIND_PERR: case RSLT_UNKN_DATA: break; default: /* * set Channel Data Length */ term_resp->v_chan_dat_lth = TRUE; if (sim_data.received_data.list_len > 255) { /* * more than 255 bytes are available in RX buffer */ term_resp->chan_dat_lth = 0xff; } else { term_resp->chan_dat_lth = (UBYTE)sim_data.received_data.list_len; } break; } /* * send Terminal Response */ MALLOC(temp_sdu, (USHORT)(sizeof(T_sdu) - 1 + MAX_STK_CMD)); temp_sdu->l_buf = MAX_STK_CMD << 3; temp_sdu->o_buf = 0; ccdRet = ccd_codeMsg (CCDENT_SAT, UPLINK, (T_MSGBUF *) temp_sdu, (UBYTE *) _decodedMsg, TERM_RESP); } CCD_END; if ( ccdRet NEQ ccdOK ) { TRACE_EVENT_P1("CCD Coding Error: %d",ccdRet ); } else { FKT_TerminalResponse (temp_sdu->buf, (USHORT)(temp_sdu->l_buf >> 3)); } MFREE(temp_sdu); } if ((sim_data.bip_rx_state EQ SIM_BIP_RX_DATA) AND (sim_data.received_data.list_len EQ 0)) { /* * set new BIP state */ #ifdef _SIMULATION_ TRACE_EVENT("bip_rx_state = IDLE"); #endif sim_data.bip_rx_state = SIM_BIP_RX_IDLE; /* * start DTI reception */ if ((sim_data.bip_state EQ SIM_BIP_CONNECTED) AND (sim_data.dti_rx_state EQ SIM_DTI_RX_IDLE)) { sim_data.dti_rx_state = SIM_DTI_RX_READY; dti_start(sim_data.hDTI, 0, 0, 0); } /* * start release timer */ if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_timer_state EQ SIM_BIP_TIMER_STOPPED) AND (sim_data.bip_tx_state EQ SIM_BIP_TX_IDLE) ) { /* * no data trafic on the BIP channel, * so use the timer */ sim_data.bip_timer_state = SIM_BIP_TIMER_START; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: start in stk_dti_bip_receive_data(..)"); #endif TIMER_START (sim_handle, SIM_BIP_TIMER, sim_data.bip_release_time); } } /* * send return value */ return func_ret; } /* stk_dti_bip_receive_data() */ #ifdef FF_SAT_E /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_udp_bind_cnf | +--------------------------------------------------------------------+ PURPOSE : Process the primitive UDP_BIND_CNF. */ GLOBAL void stk_udp_bind_cnf (T_UDP_BIND_CNF* udp_bind_cnf) { TRACE_FUNCTION ("stk_udp_bind_cnf()"); if (sim_data.dti_connection_state EQ SIM_DTI_CONNECTION_BIND) { if (udp_bind_cnf->err EQ UDP_BIND_NOERROR) { /* * store source port */ sim_data.udp_parameters.src_port[0] = ((udp_bind_cnf->port >> 8) & 0x00ff); sim_data.udp_parameters.src_port[1] = ((udp_bind_cnf->port) & 0x00ff); /* * make sending of the confirmation primitive (SIM_BIP_CONFIG_CNF) * out of "stk_dti_buffer_ready()" possible */ sim_data.dti_connection_state = SIM_DTI_CONNECTION_SETUP; /*###jk:OK? moved & changed from "stk_dti_connection_open()" */ if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START) ) { sim_data.bip_timer_state = SIM_BIP_TIMER_STOPPED; #ifdef _SIMULATION_ TRACE_EVENT("stk_udp_bind_cnf(): SIM_BIP_TIMER: stopped"); #endif TIMER_STOP (sim_handle, SIM_BIP_TIMER); } /* * update timer (if used) and DTI states */ if ((sim_data.bip_state EQ SIM_BIP_CONNECTED) AND (sim_data.bip_rx_state EQ SIM_BIP_RX_IDLE)) { /* * start reception */ sim_data.dti_rx_state = SIM_DTI_RX_READY; dti_start(sim_data.hDTI, 0, 0, 0); /* * start timer if used */ if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_tx_state EQ SIM_BIP_TX_IDLE) AND (sim_data.bip_timer_state EQ SIM_BIP_TIMER_STOPPED) ) { /* * no data trafic on the BIP channel, * so use the timer */ sim_data.bip_timer_state = SIM_BIP_TIMER_START; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: start in stk_dti_connection_opened()"); #endif TIMER_START (sim_handle, SIM_BIP_TIMER, sim_data.bip_release_time); } } /*###jk:OK?*/ } else { /* * can not open UDP port * so disconnect BIP channel from DTI */ stk_close_dti_connection(TRUE); /* * send confirm primitive */ stk_dti_inform_mmi(SIM_DTI_DISCONNECT, (UBYTE) SIM_BIP_UNKNOWN); } } /* * free primitive */ PFREE(udp_bind_cnf); } /* stk_udp_bind_cnf() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_udp_closeport_cnf | +--------------------------------------------------------------------+ PURPOSE : Process the primitive UDP_CLOSEPORT_CNF. */ GLOBAL void stk_udp_closeport_cnf ( T_UDP_CLOSEPORT_CNF* udp_closeport_cnf) { TRACE_FUNCTION ("stk_udp_closeport_cnf()"); /* * free primitive */ PFREE(udp_closeport_cnf); } /* stk_udp_closeport_cnf() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_udp_error_ind | +--------------------------------------------------------------------+ PURPOSE : Process the primitive UDP_ERROR_IND. */ GLOBAL void stk_udp_error_ind (T_UDP_ERROR_IND* udp_error_ind) { TRACE_FUNCTION ("stk_udp_error_ind()"); /* * free primitive */ PFREE(udp_error_ind); /* * generate error response */ { PALLOC(udp_error_res, UDP_ERROR_RES); PSEND(hCommUDP, udp_error_res); } } /* stk_udp_error_ind() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_udp_shutdown_ind | +--------------------------------------------------------------------+ PURPOSE : Process the primitive UDP_SHUTDOWN_IND. */ GLOBAL void stk_udp_shutdown_ind (T_UDP_SHUTDOWN_IND* udp_shutdown_ind) { TRACE_FUNCTION ("stk_udp_shutdown_ind()"); /* * send confirm primitive */ if (hCommUDP < VSI_OK) { hCommUDP = vsi_c_open (VSI_CALLER UDP_NAME); } if (hCommUDP >= VSI_OK) { PALLOC(udp_shutdown_res, UDP_SHUTDOWN_RES); PSEND(hCommUDP, udp_shutdown_res); /* * release VSI channel */ vsi_c_close (VSI_CALLER hCommUDP); hCommUDP = VSI_ERROR; } /* * close DTI connection */ if (sim_data.con_type EQ SIM_CON_TYPE_UDP) { switch(sim_data.dti_connection_state) { case SIM_DTI_CONNECTION_OPEN: case SIM_DTI_CONNECTION_SETUP: stk_close_dti_connection(TRUE); break; default: stk_close_dti_connection(FALSE); break; } /* * inform ACI about disconnection */ stk_dti_inform_mmi(SIM_DTI_DISCONNECT, (UBYTE) SIM_BIP_UNKNOWN); } } /* stk_udp_shutdown_ind() */ #endif /* FF_SAT_E */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_sim_dti_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_DTI_REQ. */ GLOBAL void stk_sim_dti_req (T_SIM_DTI_REQ* sim_dti_req) { UBYTE dti_conn; TRACE_FUNCTION ("stk_sim_dti_req()"); #ifdef _SIMULATION_ /* * set entity_name parameter */ switch(sim_dti_req->entity_name) { case 1: sim_dti_req->entity_name = (ULONG)("UDP"); break; case 2: sim_dti_req->entity_name = (ULONG)("SND"); break; case 3: sim_dti_req->entity_name = (ULONG)("L2R"); break; default: sim_dti_req->entity_name = (ULONG)(NULL); break; } #endif /* _SIMULATION_ */ /* * store the received primitive */ if (sim_data.sim_dti_req) { /* * free previous primitive before store the new one */ PFREE(sim_data.sim_dti_req); } sim_data.sim_dti_req = sim_dti_req; /* * store requested operations */ dti_conn = sim_dti_req->dti_conn; switch (dti_conn) { case SIM_DTI_DISCONNECT: /* close DTI connection */ { switch(sim_data.dti_connection_state) { case SIM_DTI_CONNECTION_OPEN: case SIM_DTI_CONNECTION_SETUP: stk_close_dti_connection(TRUE); break; default: stk_close_dti_connection(FALSE); break; } break; } case SIM_DTI_CONNECT: /* open DTI connection */ { /* * if a new DTI connection is requested close the old one before */ switch(sim_data.dti_connection_state) { case SIM_DTI_CONNECTION_OPEN: case SIM_DTI_CONNECTION_SETUP: stk_close_dti_connection(TRUE); break; default: stk_close_dti_connection(FALSE); } /* * store relevant data */ sim_data.link_id = sim_dti_req->link_id; sim_data.dti_connection_state = SIM_DTI_CONNECTION_SETUP; dti_open(sim_data.hDTI, /* DTI handle */ 0, /* instance */ 0, /* interface */ 0, /* channel */ 0, /* queue size */ sim_dti_req->dti_direction, /* direction */ FLOW_CNTRL_ENABLED, /* comm_type */ DTI_VERSION_10, /* version */ (UBYTE*)sim_dti_req->entity_name, /* entity name */ sim_dti_req->link_id); /* link identifier */ } } /* * send confirm primitive */ if (sim_data.sim_dti_req) { TRACE_EVENT_P1("if(sim_data.sim_dti_req): ~ ->dti_conn=0x%02X", sim_dti_req->dti_conn); stk_dti_inform_mmi(sim_dti_req->dti_conn, (UBYTE)SIM_BIP_UNKNOWN); } } /* stk_sim_dti_req() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_sim_bip_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_BIP_REQ. */ GLOBAL void stk_sim_bip_req (T_SIM_BIP_REQ* sim_bip_req) { UBYTE bip_conn; USHORT temp_len; T_desc2* temp_desc1; T_desc2* temp_desc2; TRACE_FUNCTION ("stk_sim_bip_req()"); /* * store the received primitive */ if (sim_data.sim_bip_req) { /* * free previous primitive before store the new one */ PFREE(sim_data.sim_bip_req); } sim_data.sim_bip_req = sim_bip_req; /* * store requested operations */ bip_conn = sim_bip_req->bip_conn; /* * resume BIP channel */ if (bip_conn & SIM_BIP_CHANNEL_RESUMED) { /* * set new suspension state */ sim_data.bip_suspend = FALSE; /* * restart timer if used */ if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_timer_state EQ SIM_BIP_TIMER_SUSPENDED) ) { sim_data.bip_timer_state = SIM_BIP_TIMER_STOPPED; if ((sim_data.bip_rx_state EQ SIM_BIP_RX_IDLE) AND (sim_data.bip_tx_state EQ SIM_BIP_TX_IDLE) ) { /* * no data trafic on the BIP channel, * so use the timer */ sim_data.bip_timer_state = SIM_BIP_TIMER_START; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: start in stk_sim_bip_req(..)"); #endif TIMER_START (sim_handle, SIM_BIP_TIMER, sim_data.bip_release_time); } } } /* * close BIP channel */ if (bip_conn & SIM_BIP_CLOSE_CHANNEL) { stk_close_bip_channel(sim_bip_req->general_result, sim_bip_req->add_info_result); } /* * open BIP channel */ if ((bip_conn & SIM_BIP_OPEN_CHANNEL) AND (sim_data.bip_state EQ SIM_BIP_CLOSED)) { /* * set new BIP state and * store BIP channel identifier */ sim_data.bip_state = SIM_BIP_OPEN; sim_data.bip_ch_id = sim_bip_req->bip_ch_id; /* * store relevant data */ sim_data.bip_release_time = (T_TIME)sim_bip_req->release_time * 100; /* convert to msec. */ if (sim_bip_req->general_result NEQ RSLT_PERF_SUCCESS) { sim_data.bip_general_result = sim_bip_req->general_result; sim_data.bip_add_info_result = sim_bip_req->add_info_result; } } /* * suspend BIP channel */ if (bip_conn & SIM_BIP_CHANNEL_SUSPENDED) { /* * set new suspension state */ sim_data.bip_suspend = TRUE; /* * stop timer if timer is used */ if (sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) { if (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START) { sim_data.bip_timer_state = SIM_BIP_TIMER_SUSPENDED; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: stopped"); #endif TIMER_STOP (sim_handle, SIM_BIP_TIMER); } else if (sim_data.bip_timer_state EQ SIM_BIP_TIMER_STOPPED) { sim_data.bip_timer_state = SIM_BIP_TIMER_SUSPENDED; } } /* * store result codes */ sim_data.bip_general_result = sim_bip_req->general_result; sim_data.bip_add_info_result = sim_bip_req->add_info_result; /* * inform SIM card */ if (sim_data.bip_tx_state EQ SIM_BIP_TX_SEND) { /* * free data of last SEND DATA message */ temp_desc1 = (T_desc2*)sim_data.data_to_send.first; sim_data.data_to_send = sim_data.prev_data_to_send; if (sim_data.data_to_send.first EQ (ULONG)NULL) { while(temp_desc1) { temp_desc2 = temp_desc1; temp_desc1 = (T_desc2*)temp_desc1->next; MFREE(temp_desc2); } } else { temp_len = 0; while((temp_desc1) AND (temp_len + temp_desc1->len) < sim_data.data_to_send.list_len) { temp_len += temp_desc1->len; temp_desc1 = (T_desc2*)temp_desc1->next; } if (temp_desc1) { temp_desc1->len = sim_data.data_to_send.list_len - temp_len; temp_desc2 = (T_desc2*)temp_desc1->next; temp_desc1->next = (ULONG)NULL; temp_desc1 = temp_desc2; while(temp_desc1) { temp_desc2 = temp_desc1; temp_desc1 = (T_desc2*)temp_desc1->next; MFREE(temp_desc2); } } } /* * set new BIP TX state */ if (sim_data.data_to_send.first EQ (ULONG)NULL) { #ifdef _SIMULATION_ TRACE_EVENT("bip_tx_state = IDLE"); #endif sim_data.bip_tx_state = SIM_BIP_TX_IDLE; } else { #ifdef _SIMULATION_ TRACE_EVENT("bip_tx_state = STORE"); #endif sim_data.bip_tx_state = SIM_BIP_TX_STORE; if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START) ) { sim_data.bip_timer_state = SIM_BIP_TIMER_STOPPED; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: stopped"); #endif TIMER_STOP (sim_handle, SIM_BIP_TIMER); } } /* * send Terminal Response */ stk_bip_send_data_terminal_response(sim_bip_req->general_result, sim_bip_req->add_info_result); /* * suspension is not triggered from a proactive_polling function call * so adjust timer and start polling */ stk_start_timer_and_poll(); } } /* * send confirm primitive */ if (sim_data.sim_bip_req) { stk_dti_inform_mmi((UBYTE) SIM_DTI_UNKNOWN, sim_bip_req->bip_conn); } } /* stk_sim_bip_req() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_sim_bip_config_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_BIP_CONFIG_REQ. */ GLOBAL void stk_sim_bip_config_req(T_SIM_BIP_CONFIG_REQ * sim_bip_config_req) { TRACE_FUNCTION ("stk_sim_bip_config_req()"); /* * store the received primitive */ if (sim_data.sim_bip_config_req) { /* * free previous primitive before store the new one */ PFREE(sim_data.sim_bip_config_req); } sim_data.sim_bip_config_req = sim_bip_config_req; /* * store relevant data */ sim_data.con_type = sim_bip_config_req->con_type; #if 0 sim_data.udp_parameters.src_ip[0] = (UBYTE)((sim_bip_config_req->local_ip >> 24) & 0x000000ff); sim_data.udp_parameters.src_ip[1] = (UBYTE)((sim_bip_config_req->local_ip >> 16) & 0x000000ff); sim_data.udp_parameters.src_ip[2] = (UBYTE)((sim_bip_config_req->local_ip >> 8) & 0x000000ff); sim_data.udp_parameters.src_ip[3] = (UBYTE)((sim_bip_config_req->local_ip) & 0x000000ff); #else sim_data.udp_parameters.src_ip[3] = (UBYTE)((sim_bip_config_req->local_ip >> 24) & 0x000000ff); sim_data.udp_parameters.src_ip[2] = (UBYTE)((sim_bip_config_req->local_ip >> 16) & 0x000000ff); sim_data.udp_parameters.src_ip[1] = (UBYTE)((sim_bip_config_req->local_ip >> 8) & 0x000000ff); sim_data.udp_parameters.src_ip[0] = (UBYTE)((sim_bip_config_req->local_ip) & 0x000000ff); #endif sim_data.udp_parameters.des_ip[0] = (UBYTE)((sim_bip_config_req->destination_ip >> 24) & 0x000000ff); sim_data.udp_parameters.des_ip[1] = (UBYTE)((sim_bip_config_req->destination_ip >> 16) & 0x000000ff); sim_data.udp_parameters.des_ip[2] = (UBYTE)((sim_bip_config_req->destination_ip >> 8) & 0x000000ff); sim_data.udp_parameters.des_ip[3] = (UBYTE)((sim_bip_config_req->destination_ip) & 0x000000ff); #if 0 sim_data.udp_parameters.des_port[0] = (UBYTE)((sim_bip_config_req->destination_port >> 8) & 0x00ff); sim_data.udp_parameters.des_port[1] = (UBYTE)((sim_bip_config_req->destination_port) & 0x00ff); #else sim_data.udp_parameters.des_port[1] = (UBYTE)((sim_bip_config_req->destination_port >> 8) & 0x00ff); sim_data.udp_parameters.des_port[0] = (UBYTE)((sim_bip_config_req->destination_port) & 0x00ff); #endif /* * UDP connection */ if (sim_data.con_type EQ SIM_CON_TYPE_UDP) { /* * open VSI channel to UDP */ if (hCommUDP < VSI_OK) { TRACE_EVENT("if(hCommUDP < VSI_OK)"); if ((hCommUDP = vsi_c_open (VSI_CALLER UDP_NAME)) < VSI_OK) { TRACE_EVENT("if ((hCommUDP = vsi_c_open (VSI_CALLER UDP_NAME)) < VSI_OK)"); /* * can not open VSI channel * so act as if DTI close was requested */ sim_data.sim_dti_req->dti_conn = SIM_DTI_DISCONNECT; TRACE_EVENT_P1(": sim_data.sim_dti_req->dti_conn=0x%02X", sim_data.sim_dti_req->dti_conn); } } /* * send UDP_BIND_REQ */ if (hCommUDP >= VSI_OK) { PALLOC(udp_bind_req, UDP_BIND_REQ); sim_data.dti_connection_state = SIM_DTI_CONNECTION_BIND; udp_bind_req->port = UDP_AUTOASSIGN_PORT; PSEND(hCommUDP, udp_bind_req); /* * send confirm primitive: * will be sent out of "stk_dti_buffer_ready()" function in case of success, * in case of udp_bind_cnf failure only indication primitive will be sent * out of "stk_udp_bind_cnf" to MMI instead. */ } } /* * bearer level connection */ else { /*###jk:OK? moved & changed from "stk_dti_connection_open()" */ if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_timer_state EQ SIM_BIP_TIMER_START) ) { sim_data.bip_timer_state = SIM_BIP_TIMER_STOPPED; #ifdef _SIMULATION_ TRACE_EVENT("stk_udp_bind_cnf(): SIM_BIP_TIMER: stopped"); #endif TIMER_STOP (sim_handle, SIM_BIP_TIMER); } /* * update timer (if used) and DTI states */ if ((sim_data.bip_state EQ SIM_BIP_CONNECTED) AND (sim_data.bip_rx_state EQ SIM_BIP_RX_IDLE)) { /* * start reception */ sim_data.dti_rx_state = SIM_DTI_RX_READY; dti_start(sim_data.hDTI, 0, 0, 0); /* * start timer if used */ if ((sim_data.bip_timer_state NEQ SIM_BIP_TIMER_NOT_USED) AND (sim_data.bip_tx_state EQ SIM_BIP_TX_IDLE) AND (sim_data.bip_timer_state EQ SIM_BIP_TIMER_STOPPED) ) { /* * no data trafic on the BIP channel, * so use the timer */ sim_data.bip_timer_state = SIM_BIP_TIMER_START; #ifdef _SIMULATION_ TRACE_EVENT("SIM_BIP_TIMER: start in stk_dti_connection_opened()"); #endif TIMER_START (sim_handle, SIM_BIP_TIMER, sim_data.bip_release_time); } } /*###jk:OK?*/ /* * make sending of the confirmation primitive (SIM_BIP_CONFIG_CNF) * out of "stk_dti_buffer_ready()" possible */ sim_data.dti_connection_state = SIM_DTI_CONNECTION_SETUP; /* * send confirm primitive: * will be sent out of "stk_dti_buffer_ready()" function in order to * prevent sending of the data to connected neighbour DTI-entity before * this entity is ready to receive data. */ #if 0 /*###jk:OK? -> */ /* * send confirm primitive */ if (sim_data.sim_bip_config_req) { PALLOC(sim_bip_config_cnf, SIM_BIP_CONFIG_CNF); PSEND(hCommMMI, sim_bip_config_cnf); } #endif } } /* stk_bip_config_req() */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_sim_eventlist_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_EVENTLIST_REQ. */ GLOBAL void stk_sim_eventlist_req ( T_SIM_EVENTLIST_REQ* sim_eventlist_req) { TRACE_FUNCTION ("stk_sim_eventlist_req()"); /* * store new state of Data available event */ sim_data.event_data_avail = sim_eventlist_req->event_data_avail; /* * free primitive */ PFREE(sim_eventlist_req); /* * send confirm primitive */ { PALLOC(sim_eventlist_cnf, SIM_EVENTLIST_CNF); sim_eventlist_cnf->event_data_avail = sim_data.event_data_avail; PSEND(hCommMMI, sim_eventlist_cnf); } } /* stk_sim_eventlist_req() */ #endif /* FF_SAT_E */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_sim_toolkit_res | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_TOOLKIT_RES. MMI sends a Terminal Response Message to SIM toolkit. */ GLOBAL void stk_sim_toolkit_res (T_SIM_TOOLKIT_RES * sim_toolkit_res) { TRACE_FUNCTION ("stk_sim_toolkit_res()"); if (sim_data.ext_sat_cmd) { FKT_TerminalResponse (sim_toolkit_res->stk_cmd.cmd, (USHORT)(sim_toolkit_res->stk_cmd.l_cmd>>3)); PFREE (sim_toolkit_res); sim_data.ext_sat_cmd = FALSE; stk_start_timer_and_poll(); } else { TRACE_EVENT("no outstanding TR"); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_sim_toolkit_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_TOOLKIT_REQ. MMI sends an Envelope Message to SIM toolkit. */ GLOBAL void stk_sim_toolkit_req (T_SIM_TOOLKIT_REQ * sim_toolkit_req) { PALLOC (sim_toolkit_cnf, SIM_TOOLKIT_CNF); sim_toolkit_cnf->stk_cmd.o_cmd = 0; sim_toolkit_cnf->req_id = sim_toolkit_req->req_id; TRACE_FUNCTION ("stk_sim_toolkit_req()"); switch (sim_toolkit_req->source) // check valid source { case SRC_MMI: case SRC_SMS: break; default: TRACE_EVENT ("SIM_TOOLKIT_REQ: invalid source"); PFREE (sim_toolkit_cnf); PFREE (sim_toolkit_req); return; } /* * Forward envelope command to SIM toolkit */ sim_toolkit_cnf->cause = FKT_Envelope (sim_toolkit_cnf->stk_cmd.cmd, sim_toolkit_req->stk_cmd.cmd, (USHORT)(sim_toolkit_req->stk_cmd.l_cmd >> 3), NOT_PRESENT_16BIT); /* * Special treatment of SW1 is required for Call Control/MO-SM Control by SIM */ if (sim_toolkit_cnf->cause NEQ SIM_NO_ERROR) { switch (sim_toolkit_req->stk_cmd.cmd[0]) /* ENVELOPE tag */ { case 0xD4: /* Call Control */ case 0xD5: /* MO-SM Control */ if (sim_data.sw1 EQ 0x6F OR sim_data.sw1 EQ 0x92) /* Card problem */ sim_toolkit_cnf->cause = SIM_NO_ERROR; break; default: break; } } if (sim_data.sim_data_len > 0) { sim_toolkit_cnf->stk_cmd.l_cmd = stk_l_cmd; stk_l_cmd = 0; } else sim_toolkit_cnf->stk_cmd.l_cmd = 0; /* * send confirmation to requesting entity */ if (sim_toolkit_req->source EQ SRC_MMI) { PSENDX (MMI, sim_toolkit_cnf); } else { PSENDX (SMS, sim_toolkit_cnf); } PFREE (sim_toolkit_req); stk_start_timer_and_poll(); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_file_update_res | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_FILE_UPDATE_RES. A File Change Notification is responded. */ GLOBAL void stk_file_update_res (T_SIM_FILE_UPDATE_RES * file_update_res) { UBYTE *p_res; // access to result code TRACE_FUNCTION ("stk_file_update_res()"); if (file_update_res->source EQ SRC_MMI) sim_data.file_change_resp &= ~1; else if (file_update_res->source EQ SRC_SMS) sim_data.file_change_resp &= ~2; else if (file_update_res->source EQ SRC_MM) sim_data.file_change_resp &= ~4; else { PFREE (file_update_res); return; } p_res = &sim_data.stk_response[sim_data.stk_response[1] + 8]; if (file_update_res->fu_rsc EQ SIM_FU_SUCC_ADD) *p_res = STK_RES_SUCC_ADD_EF_READ; if (sim_data.file_change_resp EQ 0) { FKT_TerminalResponse (sim_data.stk_response, (USHORT)sim_data.stk_resp_len); stk_start_timer_and_poll(); } PFREE (file_update_res); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_timeout | +--------------------------------------------------------------------+ PURPOSE : Process the timeout of a timer established by the SAT command TIMER MANAGEMENT. */ static const UBYTE timer_env[] = { STK_TIMER_EXPIRATION_TAG, STK_DEVICE_IDENTITY_LEN+STK_TIMER_ID_LEN+STK_TIMER_VALUE_LEN+6, STK_DEVICE_IDENTITY_TAG|STK_COMPREHENSION_REQUIRED, STK_DEVICE_IDENTITY_LEN, 0x82, 0x81, STK_TIMER_ID_TAG|STK_COMPREHENSION_REQUIRED, STK_TIMER_ID_LEN, 0, STK_TIMER_VALUE_TAG|STK_COMPREHENSION_REQUIRED, STK_TIMER_VALUE_LEN, 0, 0, 0 }; extern UBYTE pending_timers[]; extern UBYTE next_pos_to_fill; extern UBYTE next_pos_to_send; GLOBAL void stk_timeout (USHORT index) { UBYTE env[sizeof(timer_env)]; UBYTE dummy[4]; USHORT error; TRACE_FUNCTION("stk_timeout"); #ifdef FF_SAT_E /* * handle BIP timeout */ if (index EQ SIM_BIP_TIMER) { /* * close DTI connection */ switch(sim_data.dti_connection_state) { case SIM_DTI_CONNECTION_OPEN: case SIM_DTI_CONNECTION_SETUP: stk_close_dti_connection(TRUE); break; default: stk_close_dti_connection(FALSE); break; } /* * close BIP channel and inform MMI */ stk_close_bip_channel(RSLT_BEARIND_PERR, ADD_BIP_CHAN_CLOSD); stk_dti_inform_mmi(SIM_DTI_DISCONNECT, SIM_BIP_CLOSE_CHANNEL); return; } #endif /* FF_SAT_E */ if ((unsigned)(--index) >= MAX_SAT_TIMER) /* index range 0..7 */ return; if (sim_data.timer[index].active) { memcpy (env, timer_env, sizeof(timer_env)); env[8] = (UBYTE)(index + 1); /* Timer number range is 1..8 */ env[11] = sim_data.timer[index].hour; env[12] = sim_data.timer[index].minute; env[13] = sim_data.timer[index].second; error = FKT_Envelope (dummy, env, sizeof(timer_env), 0); //TISH, test patch for OMAPS00179771: SATK: Timer Expiration, modified by Jinshu Wang, 2008-09-01 //start #if 0 if (error EQ SIM_NO_ERROR) stk_start_timer_and_poll(); #else if (error EQ SIM_NO_ERROR) { stk_start_timer_and_poll(); sim_data.timer[index].active = FALSE; //modified by Jinshu Wang, 2008-09-04 if(sim_data.chk_sat_avail) { sim_data.chk_sat_avail = FALSE; stk_proactive_polling(); } return; //modified by Jinshu Wang, 2008-09-04 } #endif //end /* * If SIM response is busy(9300), we have to once retry sending * timer-expiry envelope after SIM becomes OK on getting a TR */ if (error EQ SIM_CAUSE_SAT_BUSY) { pending_timers[next_pos_to_fill] = (UBYTE) index; if (8 == next_pos_to_fill) { next_pos_to_fill = 0; } else { next_pos_to_fill++; } } sim_data.timer[index].active = FALSE; } } #ifdef TI_PS_FF_AT_P_CMD_CUST /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : stk_sim_refresh_user_res | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_REFRESH_USER_RES. MMI sends a Response Message to SIM_TOOLKIT_IND. This Primitive should not occur when cust_mode is 0 */ GLOBAL void stk_sim_refresh_user_res (T_SIM_REFRESH_USER_RES * sim_refresh_user_res) { TRACE_FUNCTION ("stk_sim_refresh_user_res()"); /* primitive should not occur for cust_mode 0 */ if (sim_data.cust_mode EQ 0) { //Handle error condition TRACE_FUNCTION_P1 ("!!!!Incorrect operation: Unexpected mode: cust_mode = %d !!!!",sim_data.cust_mode); TRACE_FUNCTION ("Primitive should not occur if cust_mode = 0"); //MFREE (sim_data.context_switch_ptr); Don't free context as it should be freed by other thread. i.e. stk_proactive_polling() PFREE (sim_refresh_user_res); return; } /* check that we are expecting primitive */ if ( sim_data.user_confirmation_expected EQ FALSE ) { //Handle error condition TRACE_FUNCTION ("!!!!Incorrect operation: user_confirmation_expected is FALSE !!!!"); TRACE_FUNCTION ("Primitive should only occur if user_confirmation_expected is TRUE"); //MFREE (sim_data.context_switch_ptr); Don't free context switch as setup can not be guaranteed to be correct. PFREE (sim_refresh_user_res); return; } else { //Reset user_confirmation_expected sim_data.user_confirmation_expected = FALSE; } if ((sim_refresh_user_res->user_accepts) EQ FALSE) { TRACE_FUNCTION ("User REJECTS Refresh Request"); FKT_TerminalResponse (sim_refresh_user_res->stk_cmd.cmd, (USHORT)(sim_refresh_user_res->stk_cmd.l_cmd>>3)); sim_data.ext_sat_cmd = FALSE; stk_start_timer_and_poll(); //process_sim_refresh() automatically frees the signal. //As we are not calling process_sim_refresh() we need to handle the freeing TRACE_ASSERT(sim_data.context_switch_ptr->sig_ptr); PFREE (sim_data.context_switch_ptr->sig_ptr); } else { TRACE_FUNCTION ("User ACCEPTS Refresh Request"); process_sim_refresh(sim_data.context_switch_ptr); TRACE_FUNCTION ("stk_sim_refresh_user_res() send end of SAT session indicator"); if ((sim_data.term_resp_sent) AND (sim_data.sat_session)) { PALLOC (sim_toolkit_ind, SIM_TOOLKIT_IND); memset (sim_toolkit_ind, 0, sizeof (T_SIM_TOOLKIT_IND)); #ifdef _SIMULATION_ TRACE_EVENT("SAT session ended"); #endif sim_data.sat_session = FALSE; sim_data.term_resp_sent = FALSE; PSENDX (MMI, sim_toolkit_ind); } } TRACE_ASSERT(sim_data.context_switch_ptr); MFREE (sim_data.context_switch_ptr); sim_data.context_switch_ptr = NULL; PFREE (sim_refresh_user_res); TRACE_FUNCTION ("stk_sim_refresh_user_res() exited"); } #endif /* TI_PS_FF_AT_P_CMD_CUST */ #endif