FreeCalypso > hg > fc-magnetite
view src/g23m-gsm/sms/sms_tlp.c @ 470:fb5c5859ad22
romvecs-patch: insert code moved into src subdir
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 25 Mar 2018 05:46:28 +0000 |
parents | 27a4235405c6 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : GSM-F&D (8411) | Modul : SMS_TLP +----------------------------------------------------------------------------- | 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 functions for the transfer layer | capability of the module Short Message Service. +----------------------------------------------------------------------------- */ #ifndef SMS_TLP_C #define SMS_TLP_C #define ENTITY_SMS /*==== INCLUDES ===================================================*/ #include <string.h> #include <stdlib.h> #include <stddef.h> #include "typedefs.h" #include "pcm.h" #include "vsi.h" #include "custom.h" #include "gsm.h" #include "message.h" #include "ccdapi.h" #include "prim.h" #include "cus_sms.h" #include "cnf_sms.h" #include "mon_sms.h" #include "pei.h" #include "tok.h" #include "sms.h" #include "gdi.h" #include "sms_em.h" /*==== EXPORT =====================================================*/ /*==== PRIVAT =====================================================*/ /*==== VARIABLES ==================================================*/ /*==== TEST =======================================================*/ /*==== FUNCTIONS ==================================================*/ /* Implements Measure# 7 */ /* +----------------------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_sim_rd_record_update_state | +----------------------------------------------------------------------------------+ PURPOSE : This routine process primitive SIM_READ_RECORD_CONF for the cases MMI_FIND_FIRST and MMI_FIND_NEXT */ LOCAL BOOL tl_sim_rd_record_update_state(T_SIM_READ_RECORD_CNF *read_cnf) { GET_INSTANCE_DATA; TRACE_FUNCTION("tl_sim_rd_record_update_state()"); if ((GET_STATE(STATE_MMI) EQ MMI_FIND_FIRST AND sms_data->sim_mem_update) OR (GET_STATE(STATE_MMI) EQ MMI_STATE_UPDATE AND sms_data->sim_mem_update)) { /* * Either the SMS record has been changed or both the SMS record * and the SMS status have been changed */ PFREE (read_cnf); sms_data->stored_mmi_state = MMI_IDLE; return TRUE; /* return; */ } else if (GET_STATE(STATE_MMI) EQ MMI_STATE_UPDATE) { /* * Only SMS record's status has been changed. */ sms_data->stored_read_cnf = read_cnf; return TRUE; /* return; */ } sms_data->stored_mmi_state = MMI_IDLE; return FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_CP | | STATE : code ROUTINE : tl_init | +--------------------------------------------------------------------+ PURPOSE : Initialize the transfer layer. */ GLOBAL void tl_init () { GET_INSTANCE_DATA; TRACE_FUNCTION ("tl_init()"); SMS_ENT_STATE(sms_data) = SMS_STATE_NOT_AVAILABLE; memset (sms_data->data, 0, sizeof (sms_data->data)); /* This is only for simulation tests*/ sms_data->data[INST_MO].ti = 6; SMS_SIM_MEM_AVAIL(sms_data) = TRUE; SMS_MEM_CFG(sms_data) = MEM_SM; SMS_MT_HANDLING(sms_data) = MT_DEF; SMS_ST_REPORT(sms_data) = DS0; SMS_SIM_PHASE(sms_data) = PHASE_2_SIM; SMS_MT_ACK_MODE(sms_data) = SMS_MHC_DEF; SMS_NETWORK(sms_data) = NW_SIM_NONE; sms_data->init_done = FALSE; SMS_SIM_PROP(sms_data).status_field = sms_data->sim_status_field; SMS_SIM_PROP(sms_data).pid_field = sms_data->sim_pid_field; SMS_SIM_PROP(sms_data).mem_type = MEM_SM; SMS_SIM_PROP(sms_data).max_record = 0; SMS_SIM_PROP(sms_data).any_valid = FALSE; /* SMS_ME_PROP(sms_data).status_and_pid = sms_data->me_status_field; */ /* SMS_ME_PROP(sms_data).status_and_pid = sms_data->me_pid_field; */ SMS_ME_PROP(sms_data).status_field = NULL; SMS_ME_PROP(sms_data).pid_field = NULL; SMS_ME_PROP(sms_data).mem_type = MEM_ME; SMS_ME_PROP(sms_data).max_record = 0; SMS_ME_PROP(sms_data).any_valid = FALSE; sms_data->sim_mem_update = FALSE; #ifdef SIM_TOOLKIT sms_data->download_sms = FALSE; sms_data->file_update_ind = NULL; sms_data->stored_mmi_state = MMI_IDLE; sms_data->stored_read_cnf = NULL; #endif SMS_RP_RCVD(sms_data) = NULL; #ifdef FF_CPHS SMS_CPHS(sms_data) = FALSE; #endif #ifdef GPRS SMS_ROUTE_PREF(sms_data) = GPRS_SMS_CCT_ONLY; #endif sms_data->pr_cntrl.delivery_state = SMS_DELIVER_STATUS_RESUME; sms_data->concat_cntrl.concatenation = FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_sim_abort_to_mmi | +--------------------------------------------------------------------+ PURPOSE : Abort a SIM related SMS command to MMI. */ LOCAL void tl_sim_abort_to_mmi (USHORT error) { GET_INSTANCE_DATA; switch (GET_STATE (STATE_MMI)) { case MMI_REPLACE: #ifdef REL99 if(SMS_INST.failed_msg_retx EQ FALSE) { #endif tl_mnsms_submit_cnf (SMS_INST.act_mem, SMS_INST.act_record, SMS_INST.tp_mr_ret, error, NULL); #ifdef REL99 } else { tl_mnsms_retrans_cnf (SMS_INST.act_mem, SMS_INST.act_record, SMS_INST.tp_mr_ret, error, NULL); } #endif break; case MMI_READ: tl_mnsms_read_cnf (SMS_INST.act_mem, SMS_INST.act_record, NULL, error); break; case MMI_WRITE: tl_mnsms_store_cnf (SMS_INST.act_mem, SMS_INST.act_record, error); break; case MMI_DELETE: tl_mnsms_delete_cnf (SMS_INST.act_mem, SMS_INST.act_record, 0, error); break; default: break; } if (sms_data->access_fifo[1] EQ ACCESS_BY_MMI) { sms_data->access_fifo[1] = ACCESS_EMPTY; } else if (sms_data->access_fifo[0] EQ ACCESS_BY_MMI) { sms_data->access_fifo[0] = ACCESS_EMPTY; } SET_STATE (STATE_MMI, MMI_IDLE); #ifdef SIM_TOOLKIT if (sms_data->file_update_ind NEQ NULL) { T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind; sms_data->file_update_ind = NULL; tl_sim_file_update_ind (file_update_ind); } if (sms_data->stored_read_cnf NEQ NULL) { /* * Resets the stored MMI state & read_cnf primitive */ sms_data->stored_mmi_state = MMI_IDLE; PFREE (sms_data->stored_read_cnf); sms_data->stored_read_cnf = NULL; } #endif } /*---- PRIMITIVES --------------------------------------------------*/ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_configure_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_CONFIGURE_REQ. */ GLOBAL void tl_mnsms_configure_req (T_MNSMS_CONFIGURE_REQ *configure_req) { register T_SMS_DATA *sms_data = GET_SMS_INSTANCE (0); TRACE_FUNCTION ("tl_mnsms_configure_req()"); if (sms_data) { sms_data->mem3 = configure_req->pref_mem_3; sms_data->mt = (configure_req->mt < MT_DEF)? configure_req->mt: MT_DEF; sms_data->ds = configure_req->ds; sms_data->mhc = configure_req->mhc; /* * If CMMS mode is enabled, store the current value of cmms_mode in sms_data */ if(configure_req->v_cmms_mode) { sms_data->cmms_mode = configure_req->cmms_mode; } /* * For CMMS if user has set the value for TMMS timer then store that * value in sms_data */ if(configure_req->v_tmms_val) { sms_data->timer_values[TMMS] = configure_req->tmms_val; } } PFREE (configure_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_mo_serv_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_MO_SERV_REQ. (set preferred destination (GPRS/GSM) for MO SM) */ #if defined GPRS GLOBAL void tl_mnsms_mo_serv_req (T_MNSMS_MO_SERV_REQ *mo_serv_req) { GET_INSTANCE_DATA; TRACE_FUNCTION ("tl_mnsms_mo_serv_req()"); /* * send MNSMS_MO_SERV_CNF with configured pref. dst */ { PALLOC (mo_serv_cnf, MNSMS_MO_SERV_CNF); memset (mo_serv_cnf, 0, sizeof (T_MNSMS_MO_SERV_CNF)); if (sms_data) /*lint !e774 always True*/ { sms_data->mo_dst_pref = mo_serv_req->mo_sms_serv; mo_serv_cnf->mo_sms_serv = sms_data->mo_dst_pref; TRACE_EVENT_P1("MO Path: %d", sms_data->mo_dst_pref); } else { mo_serv_cnf->mo_sms_serv = NOT_PRESENT_8BIT; } PSENDX (MMI, mo_serv_cnf); } PFREE (mo_serv_req); } #endif /* GPRS */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_command_cnf | +--------------------------------------------------------------------+ PURPOSE : Generate a response to the primitive MNSMS_COMMAND_REQ. */ GLOBAL void tl_mnsms_command_cnf (UBYTE tp_mr, USHORT cause, T_sms_sdu *sms_sdu) { PALLOC (command_cnf, MNSMS_COMMAND_CNF); command_cnf->tp_mr = tp_mr; command_cnf->cause = cause; if (sms_sdu NEQ NULL) memcpy (&command_cnf->sms_sdu, sms_sdu, sizeof (T_sms_sdu)); else memset (&command_cnf->sms_sdu, 0, sizeof (T_sms_sdu)); PSENDX (MMI, command_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_command_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_COMMAND_REQ. */ GLOBAL void tl_mnsms_command_req (T_MNSMS_COMMAND_REQ *command_req) { register T_SMS_DATA *sms_data = GET_SMS_INSTANCE (0); TRACE_FUNCTION ("tl_mnsms_command_req()"); if (sms_data) { switch (SMS_INST_GET_STATE (STATE_TL)) { case TL_IDLE: if (sms_timer_check(TRAM)) { tl_mnsms_command_cnf (NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL); } else { #ifdef REL99 SMS_INST.failed_msg_retx = FALSE; if(command_req->auto_rep_flag EQ AUTO_REP_FLAG_ENABLED) { SMS_INST.tl_retx = 0; } else { /* Set to the max value so that retransmission will not be done */ SMS_INST.tl_retx = TL_MAX_RETANS; } #endif /* * save sdu */ if (SMS_SDU(sms_data) NEQ NULL) { MFREE (SMS_SDU(sms_data)); } MALLOC (SMS_SDU(sms_data), sizeof(T_sms_sdu)); memcpy (SMS_SDU(sms_data), &command_req->sms_sdu, sizeof(T_sms_sdu)); /* * TL state transition TL_ESTABLISH * EST state transition EST_CMD */ SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH); SET_STATE (STATE_EST, EST_CMD); /* * establish connection */ tl_establish_connection(TRUE); } break; default: tl_mnsms_command_cnf (NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL); } } else { tl_mnsms_command_cnf (NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL); } PFREE (command_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_delete_cnf | +--------------------------------------------------------------------+ PURPOSE : Generate a response to the primitive MNSMS_DELETE_REQ. */ GLOBAL void tl_mnsms_delete_cnf (UBYTE mem_type, UBYTE record, UBYTE next_rec, USHORT error) { PALLOC (delete_cnf, MNSMS_DELETE_CNF); delete_cnf->mem_type = mem_type; delete_cnf->rec_num = record; delete_cnf->cause = error; delete_cnf->delete_rec_next = next_rec; SMS_EM_DELETE_SHORT_MESSAGE; PSENDX (MMI, delete_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_delete_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_DELETE_REQ. */ GLOBAL void tl_mnsms_delete_req (T_MNSMS_DELETE_REQ *delete_req) { register T_SMS_DATA *sms_data = GET_SMS_INSTANCE(0); UBYTE rec_num; TRACE_FUNCTION ("tl_mnsms_delete_req()"); #ifdef REL99 /* Check if the last failed message is getting deleted */ if( ( delete_req->rec_num EQ SMS_INST.failed_msg_rec_num) AND ( delete_req->mem_type EQ SMS_INST.failed_msg_mem ) AND SMS_DATA_REQ(sms_data) NEQ NULL ) { PFREE (SMS_DATA_REQ(sms_data)); SMS_DATA_REQ(sms_data) = NULL; } #endif if (sms_data NEQ NULL) { switch (SMS_INST_GET_STATE (STATE_TL)) { case TL_IDLE: switch (delete_req->mem_type) { case MEM_ME: /* * Mobile Equipment Memory */ if(delete_req->delete_status NEQ CMGD_DEL_INDEX) { if(delete_req->rec_num EQ 0) { /* Status value is given. Find the first record satisfying this status value */ rec_num = tl_search_record_for_delete (&SMS_ME_PROP(sms_data), 1, delete_req->delete_status); if(rec_num EQ SMS_RECORD_NOT_EXIST) { tl_mnsms_delete_cnf (delete_req->mem_type, 0, 0, SIM_NO_ERROR); break; } } else { if(delete_req->rec_num > sms_data->me_backup.max_record) { tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0, (USHORT)((SMS_ME_PROP(sms_data).max_record EQ 0)? SMS_CAUSE_MEM_FAIL: SMS_CAUSE_INV_INDEX)); break; } else { /* Use the record number that ACI has given */ rec_num = delete_req->rec_num; } } } else { /* There should be a valid rec_num */ if(delete_req->rec_num EQ 0 || delete_req->rec_num > sms_data->me_backup.max_record) { tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0, (USHORT)((SMS_ME_PROP(sms_data).max_record EQ 0)? SMS_CAUSE_MEM_FAIL: SMS_CAUSE_INV_INDEX)); break; } else { rec_num = delete_req->rec_num; } } if (tl_get_status (&SMS_ME_PROP(sms_data), rec_num-1) & 1) { /* * entry is used */ UBYTE data[SIZE_EF_SMS]; UBYTE next_rec_num = 0; data[0] = 0; memset (&data[1], 0xFF, SIZE_EF_SMS-1); tl_store_status (&SMS_ME_PROP(sms_data), rec_num-1, SIM_SMS_FREE); /* Implements Measure#32: Row 95 */ pcm_WriteRecord ((UBYTE *)ef_sms_id, rec_num, SIZE_EF_SMS, data); TRACE_EVENT_P1 ("mem cap avail %d", sms_data->mem_cap_avail); if (!sms_data->mem_cap_avail) { SMS_SEL_MEM(sms_data) = delete_req->mem_type; SMS_SEL_REC(sms_data) = delete_req->rec_num; GET_MO_INSTANCE(sms_data); /* * TL state transition TL_ESTABLISH * EST state transition EST_SMMA * MMI state transition MMI_DELETE * */ SET_STATE (STATE_MMI, MMI_DELETE); SET_STATE (STATE_EST, EST_SMMA); SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH); /* * 1st shot */ SMS_INST.retrans = FALSE; /* * establish connection */ tl_establish_connection(FALSE); /* * wait for processing of RP-SMMA */ PFREE (delete_req); return; } if(delete_req->delete_status NEQ CMGD_DEL_INDEX) { /* Status value is given. Find the next record satisfying this status value */ next_rec_num = tl_search_record_for_delete (&SMS_ME_PROP(sms_data), rec_num, delete_req->delete_status); } tl_mnsms_delete_cnf (delete_req->mem_type, rec_num, next_rec_num, SIM_NO_ERROR); } else { tl_mnsms_delete_cnf (delete_req->mem_type, rec_num, 0, SMS_CAUSE_INV_INDEX); } break; case MEM_SM: /* * SIM memory */ if(delete_req->delete_status NEQ CMGD_DEL_INDEX) { if(delete_req->rec_num EQ 0) { /* Status value is given. Find the first record satisfying this status value */ rec_num = tl_search_record_for_delete (&SMS_SIM_PROP(sms_data), 1, delete_req->delete_status); if(rec_num EQ SMS_RECORD_NOT_EXIST) { tl_mnsms_delete_cnf (delete_req->mem_type, 0, 0, SIM_NO_ERROR); break; } } else { if(delete_req->rec_num > sms_data->sim_backup.max_record) { tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0, SMS_CAUSE_INV_INDEX); break; } else { /* Use the record number that he has given */ rec_num = delete_req->rec_num; } } } else { /* There should be a valid rec_num */ if(delete_req->rec_num EQ 0 || delete_req->rec_num > sms_data->sim_backup.max_record) { tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0, SMS_CAUSE_INV_INDEX); break; } else { rec_num = delete_req->rec_num; } } if (tl_get_status (&SMS_SIM_PROP(sms_data), rec_num-1) & 1) { /* * entry is used */ SMS_SEL_MEM(sms_data) = delete_req->mem_type; SMS_SEL_REC(sms_data) = rec_num; SMS_REC_STATUS(sms_data) = delete_req->delete_status; tl_set_access_fifo (ACCESS_BY_MMI); SET_STATE (STATE_MMI, MMI_DELETE); SMS_INST_SET_STATE (STATE_TL, TL_OTHER); tl_sim_update_req (rec_num, SMS_RECORD_FREE, NULL); } else { tl_mnsms_delete_cnf (delete_req->mem_type, rec_num, 0, SMS_CAUSE_INV_INDEX); } break; case MEM_SR: tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0, SMS_CAUSE_MEM_FAIL); break; default: tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0, SMS_CAUSE_PARAM_WRONG); break; } break; default: tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0, SMS_CAUSE_ENTITY_BUSY); break; } } else tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0, SMS_CAUSE_ENTITY_BUSY); PFREE (delete_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_read_cnf | +--------------------------------------------------------------------+ PURPOSE : Generate an error response to the primitive MNSMS_READ_REQ. */ GLOBAL void tl_mnsms_read_cnf (UBYTE mem_type, UBYTE record, UBYTE *data, USHORT error) { GET_INSTANCE_DATA; PALLOC (read_cnf, MNSMS_READ_CNF); /* T_MNSMS_READ_CNF */ read_cnf->mem_type = mem_type; read_cnf->rec_num = record; switch (mem_type) { case MEM_SM: if (sms_data->init_done) { read_cnf->rec_next = tl_search_record (&SMS_SIM_PROP(sms_data), (USHORT)(record + 1), SMS_REC_STATUS(sms_data)); read_cnf->rec_max = SMS_SIM_PROP(sms_data).max_record; } else { read_cnf->rec_next = SMS_RECORD_NOT_EXIST; read_cnf->rec_max = SMS_RECORD_NOT_EXIST; } break; case MEM_ME: read_cnf->rec_next = tl_search_record (&SMS_ME_PROP(sms_data), (USHORT)(record + 1), SMS_REC_STATUS(sms_data)); read_cnf->rec_max = SMS_ME_PROP(sms_data).max_record; break; default: read_cnf->rec_next = SMS_RECORD_NOT_EXIST; read_cnf->rec_max = SMS_RECORD_NOT_EXIST; break; } read_cnf->cause = error; read_cnf->rec_status = SMS_RECORD_NOT_EXIST; /* ffs */ if (data NEQ NULL) { read_cnf->status = data[0]; read_cnf->sms_sdu.l_buf = SIM_PDU_BIT_LEN; read_cnf->sms_sdu.o_buf = 0; memcpy (read_cnf->sms_sdu.buf, &data[1], SIM_PDU_LEN); tl_adjust_message_len (SMS_VT_SIM_PDU, (BUF_tpdu *)&read_cnf->sms_sdu); } else { if (record EQ SMS_RECORD_NOT_EXIST) { read_cnf->status = SMS_RECORD_FREE; } else { switch (mem_type) { case MEM_ME: read_cnf->status = tl_get_status (&SMS_ME_PROP(sms_data), record-1); break; case MEM_SM: read_cnf->status = tl_get_status (&SMS_SIM_PROP(sms_data), record-1); break; default: read_cnf->status = SMS_RECORD_FREE; break; } } memset (&read_cnf->sms_sdu, 0, sizeof(T_sms_sdu)); } PSENDX (MMI, read_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_read_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_READ_REQ. */ GLOBAL void tl_mnsms_read_req (T_MNSMS_READ_REQ *read_req) { register T_SMS_DATA *sms_data = GET_SMS_INSTANCE(0); TRACE_FUNCTION ("tl_mnsms_read_req()"); if (sms_data) { switch (SMS_INST_GET_STATE (STATE_TL)) { case TL_IDLE: SMS_READ_MODE(sms_data) = read_req->read_mode; switch (read_req->mem_type) { case MEM_ME: /* Mobile Equipment Memory */ tl_read_me_memory (read_req->rec_num, read_req->status); break; case MEM_SM: /* SIM memory */ if (sms_data->init_done) { tl_read_sim_memory (read_req->rec_num, read_req->status); } else { tl_mnsms_read_cnf (read_req->mem_type, read_req->rec_num, NULL, SMS_CAUSE_ENTITY_BUSY); } break; case MEM_SR: tl_mnsms_read_cnf (read_req->mem_type, read_req->rec_num, NULL, SMS_CAUSE_MEM_FAIL); break; default: tl_mnsms_read_cnf (read_req->mem_type, read_req->rec_num, NULL, SMS_CAUSE_PARAM_WRONG); break; } break; default: tl_mnsms_read_cnf (read_req->mem_type, read_req->rec_num, NULL, SMS_CAUSE_ENTITY_BUSY); break; } } else tl_mnsms_read_cnf (read_req->mem_type, read_req->rec_num, NULL, SMS_CAUSE_ENTITY_BUSY); PFREE (read_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_store_cnf | +--------------------------------------------------------------------+ PURPOSE : Generate a response to the primitive MNSMS_STORE_REQ. */ GLOBAL void tl_mnsms_store_cnf (UBYTE mem_type, UBYTE record, USHORT error) { PALLOC (store_cnf, MNSMS_STORE_CNF); store_cnf->mem_type = mem_type; store_cnf->rec_num = record; store_cnf->cause = error; PSENDX (MMI, store_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_store_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_STORE_REQ. */ GLOBAL void tl_mnsms_store_req (T_MNSMS_STORE_REQ *store_req) { USHORT index; UBYTE dummy; int byte_len; BOOL mem_full = FALSE; register T_SMS_DATA *sms_data = GET_SMS_INSTANCE(0); TRACE_FUNCTION ("tl_mnsms_store_req()"); #ifdef REL99 /* Check if the last failed message is getting replaced */ if( ( store_req->condx NEQ SMS_CONDX_OVR_NON ) AND ( store_req->rec_num EQ SMS_INST.failed_msg_rec_num ) AND ( store_req->mem_type EQ SMS_INST.failed_msg_mem ) AND SMS_DATA_REQ(sms_data) NEQ NULL ) { PFREE (SMS_DATA_REQ(sms_data)); SMS_DATA_REQ(sms_data) = NULL; } #endif if (sms_data NEQ NULL) { switch (SMS_INST_GET_STATE (STATE_TL)) { case TL_IDLE: if (tl_check_status_value (store_req->status) EQ NOT_PRESENT_8BIT) { /* invalid status value */ tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num, SMS_CAUSE_PARAM_WRONG); break; } switch (store_req->mem_type) { case MEM_SM: if (store_req->rec_num EQ SMS_RECORD_NOT_EXIST) { if ((index = tl_get_free_space (MEM_SM)) EQ 0) mem_full = TRUE; SMS_EM_SET_CHANGE_FLAG_1; } else { if (store_req->rec_num > SMS_SIM_PROP(sms_data).max_record) index = 0; else if (store_req->condx EQ SMS_CONDX_OVR_NON) { if ((tl_get_status (&SMS_SIM_PROP(sms_data), store_req->rec_num-1) & 1) EQ SMS_RECORD_FREE) index = store_req->rec_num; else index = 0; } else if (store_req->condx EQ SMS_CONDX_OVR_MO) { switch (tl_get_status (&SMS_SIM_PROP(sms_data), store_req->rec_num-1) & 7) { case SMS_RECORD_STO_UNSENT: case SMS_RECORD_STO_SENT: index = store_req->rec_num; break; default: index = 0; break; } } else index = store_req->rec_num; SMS_EM_SET_CHANGE_FLAG_2; } break; case MEM_ME: if (store_req->rec_num EQ SMS_RECORD_NOT_EXIST) { if ((index = tl_get_free_space (MEM_ME)) EQ 0) mem_full = TRUE; SMS_EM_SET_CHANGE_FLAG_1; } else { if (store_req->condx EQ SMS_CONDX_OVR_NON) { if ((tl_get_status (&SMS_ME_PROP(sms_data), store_req->rec_num-1) & 1) EQ SMS_RECORD_FREE) index = store_req->rec_num; else index = 0; } else if (store_req->condx EQ SMS_CONDX_OVR_MO) { switch (tl_get_status (&SMS_ME_PROP(sms_data), store_req->rec_num-1) & 7) { case SMS_RECORD_STO_UNSENT: case SMS_RECORD_STO_SENT: index = store_req->rec_num; break; default: index = 0; break; } } else index = store_req->rec_num; SMS_EM_SET_CHANGE_FLAG_2; } break; case MEM_SR: tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num, SMS_CAUSE_MEM_FAIL); PFREE (store_req); return; default: tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num, SMS_CAUSE_PARAM_WRONG); PFREE (store_req); return; } if (index > 0) { /* * storage available */ byte_len = (int)store_req->sms_sdu.l_buf >> 3; if (store_req->mem_type EQ MEM_SM) { /* * SIM card memory */ tl_store_status (&SMS_SIM_PROP(sms_data), index-1, SIM_SMS_PENDING); SMS_REC_STATUS(sms_data) = store_req->status; tl_get_pid_dcs (store_req->status, &store_req->sms_sdu, &SMS_PID(sms_data), &dummy); memset (&store_req->sms_sdu.buf[byte_len], NOT_PRESENT_8BIT, (SIM_LENGTH_SMS_RECORD-1) - byte_len); tl_set_access_fifo (ACCESS_BY_MMI); SET_STATE (STATE_MMI, MMI_WRITE); SMS_INST_SET_STATE (STATE_TL, TL_OTHER); tl_sim_update_req ((UBYTE)index, store_req->status, store_req->sms_sdu.buf); break; } else { /* * memory type is mobile memory */ UBYTE data[SIZE_EF_SMS]; data[0] = store_req->status; memcpy (&data[1], store_req->sms_sdu.buf, byte_len); memset (&data[byte_len + 1], NOT_PRESENT_8BIT, (SIM_LENGTH_SMS_RECORD-1) - byte_len); /* Implements Measure#32: Row 97 */ if (pcm_WriteRecord ((UBYTE *)ef_sms_id, index, SIZE_EF_SMS, data) EQ PCM_OK) { UBYTE pid; SMS_EM_STORE_MO_SHORT_MESSAGE; SMS_EM_CHANGE_SHORT_MESSAGE; tl_store_status (&SMS_ME_PROP(sms_data), index-1, store_req->status); tl_get_pid_dcs (store_req->status, &store_req->sms_sdu, &pid, &dummy); tl_store_pid (&SMS_ME_PROP(sms_data), index-1, pid); tl_mnsms_store_cnf (store_req->mem_type, (UBYTE)index, SMS_NO_ERROR); } else tl_mnsms_store_cnf (store_req->mem_type, (UBYTE)index, SMS_CAUSE_MEM_FAIL); } } else tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num, (USHORT)((mem_full)? SMS_CAUSE_MEM_FULL: SMS_CAUSE_INV_INDEX)); break; default: tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num, SMS_CAUSE_ENTITY_BUSY); break; } } else tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num, SMS_CAUSE_ENTITY_BUSY); PFREE (store_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_submit_cnf | +--------------------------------------------------------------------+ PURPOSE : Generate a response to the primitive MNSMS_SUBMIT_REQ. */ GLOBAL void tl_mnsms_submit_cnf (UBYTE mem_type, UBYTE record, UBYTE tp_mr, USHORT cause, T_sms_sdu *sms_sdu) { PALLOC (submit_cnf, MNSMS_SUBMIT_CNF); TRACE_EVENT_P1 ("cause = %04x", cause); submit_cnf->mem_type = mem_type; submit_cnf->rec_num = record; submit_cnf->tp_mr = tp_mr; submit_cnf->cause = cause; if (sms_sdu NEQ NULL) memcpy (&submit_cnf->sms_sdu, sms_sdu, sizeof (T_sms_sdu)); else memset (&submit_cnf->sms_sdu, 0, sizeof (T_sms_sdu)); PSENDX (MMI, submit_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_submit_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_SUBMIT_REQ. */ GLOBAL void tl_mnsms_submit_req (T_MNSMS_SUBMIT_REQ *submit_req) { UBYTE ti; register T_SMS_DATA *sms_data = GET_SMS_INSTANCE(0); TRACE_FUNCTION ("tl_mnsms_submit_req()"); TRACE_EVENT_P2 ("mem_type = %02X, rec_num = %02X", submit_req->mem_type, submit_req->rec_num); if (sms_data) { switch (SMS_INST_GET_STATE (STATE_TL)) { case TL_SEND_CONTD: /* * stop timer TLCT */ sms_timer_stop(TLCT); /* * stop timer TMMS */ sms_timer_stop(TMMS); case TL_IDLE: if (sms_timer_check(TRAM)) { /* * MNSMS_SUBMIT_CNF */ tl_mnsms_submit_cnf (submit_req->mem_type, submit_req->rec_num, NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL); break; } /* * save submit request with sms sdu */ SMS_SEL_MEM(sms_data) = submit_req->mem_type; SMS_SEL_REC(sms_data) = submit_req->rec_num; SMS_CONDX(sms_data) = submit_req->condx; SMS_MODIFY(sms_data) = submit_req->modify; if (SMS_SDU(sms_data) NEQ NULL) { MFREE (SMS_SDU(sms_data)); } MALLOC (SMS_SDU(sms_data), sizeof(T_sms_sdu)); memcpy (SMS_SDU(sms_data), &submit_req->sms_sdu, sizeof(T_sms_sdu)); /* * check whether concatenated */ if (!tl_concat_check(SMS_SDU(sms_data))) { /* * error understanding the sdu */ TRACE_ERROR ("error with concat sim pdu"); /* * negative response MNSMS_SUBMIT_CNF */ tl_mnsms_submit_cnf (submit_req->mem_type, submit_req->rec_num, NOT_PRESENT_8BIT, SMS_CAUSE_PARAM_WRONG, NULL); /* * Send MNSMS_REPORT_IND if cmms_mode is equal 1or 2 */ if(CMMS_ACTIVE) { tl_mnsms_cmms_end_ind(); } /* * give up */ MFREE (SMS_SDU(sms_data)); PFREE (submit_req); return; } #ifdef REL99 /* Check whether MO msg is sent thru retransmission request. Initially False */ SMS_INST.failed_msg_retx = FALSE; if(submit_req->auto_rep_flag EQ AUTO_REP_FLAG_ENABLED) { SMS_INST.tl_retx = 0; } else { /* Set to the max value so that retransmission will not be done */ SMS_INST.tl_retx = TL_MAX_RETANS; } #endif /* * TL state transition TL_ESTABLISH * EST state transition EST_SEND */ SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH); SET_STATE (STATE_EST, EST_SEND); /* * establish connection */ ti = SMS_INST.ti; tl_establish_connection(TRUE); /* * concat control: if needed, release previous connection */ if ((sms_data->concat_cntrl.concatenation EQ TRUE) AND (sms_data->concat_cntrl.release_pending EQ TRUE)) { sms_data->concat_cntrl.release_pending = FALSE; /* * RL_RELEASE_REQ ==> */ rl_release_req(ti); /* * check for end of concatenation */ if (sms_data->concat_cntrl.end EQ TRUE) { /* * end of concatenation */ sms_data->concat_cntrl.concatenation = FALSE; } break; } /* * cmms control: if needed, release previous connection */ if(sms_data->cmms_release_pending EQ TRUE) { sms_data->cmms_release_pending = FALSE; /* * Release the previous active MM connection */ rl_release_req(ti); } break; default: /* * MNSMS_SUBMIT_CNF */ tl_mnsms_submit_cnf (submit_req->mem_type, submit_req->rec_num, NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL); } } else { /* * MNSMS_SUBMIT_CNF */ tl_mnsms_submit_cnf (submit_req->mem_type, submit_req->rec_num, NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL); } PFREE (submit_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_error_ind | +--------------------------------------------------------------------+ PURPOSE : Build and send the primitive MNSMS_ERROR_IND. */ GLOBAL void tl_mnsms_error_ind (USHORT error) { PALLOC (error_ind, MNSMS_ERROR_IND); error_ind->cause = error; PSENDX (MMI, error_ind); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_ack_res | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_ACK_RES. */ GLOBAL void tl_mnsms_ack_res (T_MNSMS_ACK_RES *ack_res) { GET_INSTANCE_DATA; TRACE_FUNCTION ("tl_mnsms_ack_res()"); if (sms_data) /*lint !e774 always True*/ { GET_MT_INSTANCE(sms_data); /* MT operation */ if (SMS_MT_ACK_MODE(sms_data) NEQ SMS_MHC_PH2PLUS) { tl_mnsms_error_ind (SMS_CAUSE_OPER_NOT_ALLW); } else switch (SMS_INST_GET_STATE (STATE_TL)) { case TL_RECEIVE: if (sms_timer_check(TR2M)) { T_rp_user_data *rp_ud; int sdu_ofs; MALLOC (rp_ud, sizeof(T_rp_user_data)); CCD_START; sdu_ofs = ack_res->sms_sdu.buf[ack_res->sms_sdu.o_buf >> 3] + 1; rp_ud->tpdu.o_tpdu = 0; if (ack_res->sms_sdu.l_buf >= (sdu_ofs << 3) + 2) /* TP-MTI present */ { rp_ud->tpdu.l_tpdu = ack_res->sms_sdu.l_buf - (sdu_ofs << 3); memcpy (rp_ud->tpdu.b_tpdu, &ack_res->sms_sdu.buf[sdu_ofs], rp_ud->tpdu.l_tpdu >> 3); rp_ud->tp_mti = rp_ud->tpdu.b_tpdu[0] & 3; rp_ud->v_tpdu = TRUE; } else { rp_ud->tpdu.l_tpdu = 0; rp_ud->tp_mti = NOT_PRESENT_8BIT; rp_ud->v_tpdu = FALSE; } if (ack_res->resp EQ SMS_RP_ACK) rl_report_req_ack (rp_ud); else { if (!rp_ud->v_tpdu) { rp_ud->tp_mti = rp_ud->tpdu.b_tpdu[0] = SMS_DELIVER_REPORT; rp_ud->tpdu.b_tpdu[1] = SMS_FCS_UNSPECIFIED; /* TP-FCS */ rp_ud->tpdu.b_tpdu[2] = 0; /* TP-PI */ rp_ud->tpdu.l_tpdu = 24; /* 3 bytes */ rp_ud->v_tpdu = TRUE; } rl_report_req_error (SMS_RP_CS_PROTOCOL_ERROR, rp_ud); /* * RL_RELEASE_REQ ==> */ rl_release_req(SMS_INST.ti); } CCD_END; MFREE (rp_ud); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); break; } /*FALLTHROUGH*/ /*lint -fallthrough*/ default: tl_mnsms_error_ind (SMS_CAUSE_UNEXP_CNMA); break; } } PFREE (ack_res); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_pause_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_PAUSE_REQ. */ GLOBAL void tl_mnsms_pause_req (T_MNSMS_PAUSE_REQ *pause_req) { TRACE_FUNCTION ("tl_mnsms_pause_req()"); tl_pause(); PFREE (pause_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_resume_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_RESUME_REQ. */ GLOBAL void tl_mnsms_resume_req (T_MNSMS_RESUME_REQ *resume_req) { TRACE_FUNCTION ("tl_mnsms_resume_req()"); tl_resume(); PFREE (resume_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_query_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_QUERY_REQ. */ GLOBAL void tl_mnsms_query_req (T_MNSMS_QUERY_REQ *query_req) { TRACE_FUNCTION ("tl_mnsms_query_req()"); switch (query_req->query_type) { case SMS_QUERY_DELIVER_STATUS: tl_query_deliver_status(); break; default: TRACE_ERROR("sms query type unknown!"); } PFREE (query_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_resume_cnf | +--------------------------------------------------------------------+ PURPOSE : Generate a response to the primitive MNSMS_RESUME_REQ. */ GLOBAL void tl_mnsms_resume_cnf ( USHORT cause ) { PALLOC (resume_cnf, MNSMS_RESUME_CNF); resume_cnf->cause = cause; PSENDX (MMI, resume_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_query_cnf | +--------------------------------------------------------------------+ PURPOSE : Generate a response to the primitive MNSMS_QUERY_REQ. */ GLOBAL void tl_mnsms_query_cnf ( U8 query_type, U8 status ) { switch (query_type) { case SMS_QUERY_DELIVER_STATUS: { PALLOC (query_cnf, MNSMS_QUERY_CNF); query_cnf->query_type = SMS_QUERY_DELIVER_STATUS; query_cnf->v_deliver_status = 1; query_cnf->deliver_status = status; PSENDX (MMI, query_cnf); } break; default: TRACE_ERROR("sms query type unknown!"); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_sim_sms_insert_ind | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_SMS_INSERT_IND. */ GLOBAL void tl_sim_sms_insert_ind (T_SIM_SMS_INSERT_IND *insert_ind) { UBYTE i; GET_INSTANCE_DATA; TRACE_FUNCTION ("tl_sim_sms_insert_ind()"); if (sms_data) /*lint !e774 always True*/ { tl_sim_abort_to_mmi (SMS_CAUSE_SIM_BUSY); sms_data->init_done = FALSE; tl_mnsms_report_ind (SMS_ENT_STATE(sms_data) = SMS_STATE_INITIALISING); /* * copy SMS initialisation parameter */ SMS_SIM_PHASE(sms_data) = insert_ind->phase; SMS_INST.tp_mr = insert_ind->tp_mr; /* * memory capacity exceeded notification flag */ switch (insert_ind->mem_cap_avail) { case SIM_SMS_MEM_FULL: /* * Notification Flag = TRUE */ TRACE_EVENT("SIM_SMS_MEM_FULL => Notification Flag = TRUE"); break; case SIM_SMS_MEM_AVAIL: /* * Notification Flag = FALSE */ TRACE_EVENT("SIM_SMS_MEM_AVAIL => Notification Flag = FALSE"); break; case SIM_SMS_NO_MEM: /* * SMS storage on SIM not present */ TRACE_EVENT("SIM_SMS_NO_MEM"); break; default: TRACE_ERROR("invalid mem cap avail information from sim"); } SMS_SIM_MEM_AVAIL(sms_data) = insert_ind->mem_cap_avail & 1; SMS_SAT_DWNLD(sms_data) = insert_ind->download_sms; /* * scan status and protocol identifier for all SMS entries * first one in tl_find_first, the rest with the for loop * in mobile memory */ tl_find_first (MEM_ME); for (i = 2; i <= sms_data->me_backup.max_record; i++) tl_find_next (MEM_ME, i); /* * check for existing but empty memory */ if (SMS_ME_PROP(sms_data).max_record > 0 AND !SMS_ME_PROP(sms_data).any_valid) tl_message_ind_from_sim (MEM_ME, 0, SMS_ME_PROP(sms_data).max_record, NULL); /* * scan status and protocol identifier for all SMS entries * in sim memory */ #ifdef FF_CPHS SET_STATE (STATE_MMI, MMI_FIND_FIRST); tl_sim_read_req (SIM_CPHS_VMW, 1); #elif defined FF_SMS_NW_RCG_SIM SET_STATE (STATE_MMI, MMI_FIND_FIRST); tl_sim_read_req (SIM_IMSI, 9); #else tl_find_first (MEM_SM); #endif } PFREE (insert_ind); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_sim_read_cnf | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_READ_CNF. */ #if defined(SIM_TOOLKIT) OR defined(FF_CPHS) OR defined(FF_SMS_NW_RCG_SIM) GLOBAL void tl_sim_read_cnf (T_SIM_READ_CNF *read_cnf) { GET_INSTANCE_DATA; USHORT datafield; TRACE_FUNCTION ("tl_sim_file_update_ind()"); datafield = sms_data->sms_sim_access_info[read_cnf->req_id].datafield; sms_data->sms_sim_access_info[read_cnf->req_id].entry_used = FALSE; if (sms_data) { switch (GET_STATE (STATE_MMI)) { case MMI_STATE_UPDATE: /* * EF_SMSS has been updated by SAT. */ if (read_cnf->cause EQ SIM_NO_ERROR) { /* Fetch TP-MR value out of EF_SMSS */ SMS_INST.tp_mr = read_cnf->trans_data[0]; if (sms_data->mem_cap_avail NEQ (read_cnf->trans_data[1] & 1)) { /* * The memory capacity available flag has been changed. * Re-read EF_SMS also even in case this has not been announced * by the SIM application. */ sms_data->mem_cap_avail = read_cnf->trans_data[1] & 1; sms_data->sim_mem_update = TRUE; } else { SET_STATE (STATE_MMI, MMI_IDLE); } } if (sms_data->sim_mem_update) { tl_mnsms_report_ind (SMS_ENT_STATE(sms_data) = SMS_STATE_INITIALISING); tl_find_first (MEM_SM); #ifdef SIM_TOOLKIT if (sms_data->stored_read_cnf NEQ NULL) { /* * Resets the stored MMI state & read_cnf primitive */ sms_data->stored_mmi_state = MMI_IDLE; PFREE (sms_data->stored_read_cnf); sms_data->stored_read_cnf = NULL; } #endif /* SIM_TOOLKIT */ } else { PALLOC (file_update_res, SIM_FILE_UPDATE_RES); file_update_res->fu_rsc = SIM_FU_SUCCESS; file_update_res->source = SRC_SMS; PSENDX (SIM, file_update_res); } #ifdef SIM_TOOLKIT /* * If the SMS has not yet completed reading all the records, start from * the place where it has left earlier. */ if( sms_data->stored_read_cnf NEQ NULL) { SET_STATE(STATE_MMI, sms_data->stored_mmi_state); tl_set_access_fifo (ACCESS_BY_MMI); tl_sim_read_record_cnf(sms_data->stored_read_cnf); sms_data->stored_mmi_state = MMI_IDLE; sms_data->stored_read_cnf = NULL; } #endif /* SIM_TOOLKIT */ break; #ifdef FF_CPHS case MMI_FIND_FIRST: /* CPHS Voice Message Waiting flag existent? */ #ifdef FF_SMS_NW_RCG_SIM if ( datafield EQ SIM_CPHS_VMW) { SMS_CPHS(sms_data) = read_cnf->cause EQ SIM_NO_ERROR; tl_sim_read_req (SIM_IMSI, 9); break; } else if (datafield EQ SIM_IMSI AND read_cnf->cause EQ SIM_NO_ERROR) { tl_check_network_on_sim (read_cnf->trans_data); } tl_find_first (MEM_SM); #else SMS_CPHS(sms_data) = datafield EQ SIM_CPHS_VMW AND read_cnf->cause EQ SIM_NO_ERROR; tl_find_first (MEM_SM); #endif #elif defined FF_SMS_NW_RCG_SIM case MMI_FIND_FIRST: /* SIM operator determination required? */ if (read_cnf->cause EQ SIM_NO_ERROR) tl_check_network_on_sim (read_cnf->trans_data); tl_find_first (MEM_SM); break; #endif default: break; } } PFREE (read_cnf); } #endif /* SIM_TOOLKIT OR FF_CPHS */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLF | | STATE : code ROUTINE : tl_sim_update_rec_cnf_mmi | +--------------------------------------------------------------------+ PURPOSE : Processing the function TL_SIM_UPDATE_REC_CNF_MMI. */ LOCAL void tl_sim_update_rec_cnf_mmi ( T_SIM_UPDATE_RECORD_CNF *update_cnf) { GET_INSTANCE_DATA; UBYTE next_rec_num=0,record; TRACE_FUNCTION ("tl_sim_update_rec_cnf_mmi()"); record = sms_data->sms_sim_access_info[update_cnf->req_id].rec_num; sms_data->sms_sim_access_info[update_cnf->req_id].entry_used = FALSE; switch (GET_STATE (STATE_MMI)) { case MMI_READ_STATE_UPDATE: if (update_cnf->cause EQ SIM_NO_ERROR AND record EQ SMS_SEL_REC(sms_data)) { /* * update status byte */ tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SMS_RECORD_REC_READ); } if (SMS_READ_MODE(sms_data) EQ READ_STATUS_CHANGE) { tl_mnsms_read_cnf (MEM_SM, SMS_SEL_REC(sms_data), NULL, SIM_NO_ERROR); } else { tl_mnsms_read_cnf (MEM_SM, SMS_SEL_REC(sms_data), SMS_SIM_READ(sms_data)->linear_data, SIM_NO_ERROR); PFREE (SMS_SIM_READ(sms_data)); SMS_SIM_READ(sms_data) = NULL; } SMS_READ_MODE(sms_data) = READ_NORMAL; SMS_INST_SET_STATE (STATE_TL, TL_IDLE); break; case MMI_WRITE: if (update_cnf->cause EQ SIM_NO_ERROR) { /* * update status byte */ tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SMS_REC_STATUS(sms_data)); tl_store_pid (&SMS_SIM_PROP(sms_data), record-1, SMS_PID(sms_data)); SMS_EM_STORE_MO_SHORT_MESSAGE_2; SMS_EM_CHANGE_SHORT_MESSAGE_2; } else { tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_FREE); } tl_mnsms_store_cnf (MEM_SM, record, update_cnf->cause); SMS_READ_MODE(sms_data) = READ_NORMAL; SMS_INST_SET_STATE (STATE_TL, TL_IDLE); break; case MMI_DELETE: if (record EQ SMS_SEL_REC(sms_data)) { if (update_cnf->cause EQ SIM_NO_ERROR) { tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_FREE); TRACE_EVENT_P1 ("mem cap avail %d", sms_data->mem_cap_avail); if (!sms_data->mem_cap_avail) { GET_MO_INSTANCE(sms_data); /* * TL state transition TL_ESTABLISH * EST state transition EST_SMMA */ SET_STATE (STATE_EST, EST_SMMA); SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH); /* * 1st shot */ SMS_INST.retrans = FALSE; /* * establish connection */ tl_establish_connection(FALSE); /* * wait for processing of RP-SMMA */ return; } if(SMS_REC_STATUS(sms_data) NEQ CMGD_DEL_INDEX) { /* Status value is given. Find the next record satisfying this status value */ next_rec_num = tl_search_record_for_delete (&SMS_SIM_PROP(sms_data), record, SMS_REC_STATUS(sms_data)); TRACE_EVENT_P1 ("tl_sim_update_rec_cnf_mmi :: next_rec_num=%d", next_rec_num); } tl_mnsms_delete_cnf (MEM_SM, record, next_rec_num, SIM_NO_ERROR); } else tl_mnsms_delete_cnf (MEM_SM, record, 0, update_cnf->cause); } else tl_mnsms_delete_cnf (MEM_SM, record, 0, SMS_CAUSE_INV_INDEX); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); break; case MMI_REPLACE: if (record EQ SMS_SEL_REC(sms_data)) { if (update_cnf->cause EQ SIM_NO_ERROR) { #ifdef REL99 if(SMS_INST.failed_msg_retx EQ FALSE) { #endif tl_mnsms_submit_cnf (MEM_SM, record, SMS_TP_REF_RET(sms_data), SMS_NO_ERROR, SMS_SDU(sms_data)); #ifdef REL99 } else { tl_mnsms_retrans_cnf (MEM_SM, record, SMS_TP_REF_RET(sms_data), SMS_NO_ERROR, SMS_SDU(sms_data)); } #endif /* * update status byte */ tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SMS_RECORD_STO_SENT); tl_store_pid (&SMS_SIM_PROP(sms_data), record-1, SMS_PID_DEFAULT); } else { #ifdef REL99 if(SMS_INST.failed_msg_retx EQ FALSE) { #endif tl_mnsms_submit_cnf (MEM_SM, SMS_RECORD_NOT_EXIST, SMS_TP_REF_RET(sms_data), update_cnf->cause, SMS_SDU(sms_data)); #ifdef REL99 } else { tl_mnsms_retrans_cnf (MEM_SM, SMS_RECORD_NOT_EXIST, SMS_TP_REF_RET(sms_data), update_cnf->cause, SMS_SDU(sms_data)); } #endif tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SMS_RECORD_FREE); /* reset reservation */ } } else tl_mnsms_submit_cnf (MEM_SM, record, SMS_TP_REF_RET(sms_data), SMS_CAUSE_INV_INDEX, SMS_SDU(sms_data)); if (SMS_SDU(sms_data) NEQ NULL) { MFREE (SMS_SDU(sms_data)); SMS_SDU(sms_data) = NULL; } SMS_SEL_REC(sms_data) = SMS_RECORD_NOT_EXIST; /* * concat control */ if (sms_data->concat_cntrl.concatenation EQ TRUE) { /* * start timer TLCT for next submit req supervision */ sms_timer_start(TLCT); /* * TL State Transition TL_SEND_CONTD */ SMS_INST_SET_STATE (STATE_TL, TL_SEND_CONTD); /* * remember to release connection */ sms_data->concat_cntrl.release_pending = TRUE; } else { /* * TL State Transition TL_IDLE */ SMS_INST_SET_STATE (STATE_TL, TL_IDLE); } break; default: assert (GET_STATE (STATE_MMI) EQ MMI_IDLE); /* illegal state */ break; } SET_STATE (STATE_MMI, MMI_IDLE); #ifdef SIM_TOOLKIT if (sms_data->file_update_ind NEQ NULL) { T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind; sms_data->file_update_ind = NULL; tl_sim_file_update_ind (file_update_ind); } #endif } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLF | | STATE : code ROUTINE : tl_sim_update_rec_cnf_net | +--------------------------------------------------------------------+ PURPOSE : Processing the function TL_SIM_UPDATE_REC_CNF_NET. */ LOCAL void tl_sim_update_rec_cnf_net (T_SIM_UPDATE_RECORD_CNF *update_cnf) { GET_INSTANCE_DATA; UBYTE record; UBYTE data[SIZE_EF_SMS]; TRACE_FUNCTION ("tl_sim_update_rec_cnf_net()"); record = sms_data->sms_sim_access_info[update_cnf->req_id].rec_num; sms_data->sms_sim_access_info[update_cnf->req_id].entry_used = FALSE; CCD_START; switch (GET_STATE (STATE_NET)) { case NET_WRITE: if (update_cnf->cause EQ SIM_NO_ERROR) { /* * update status byte */ tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SMS_RECORD_REC_UNREAD); tl_store_pid (&SMS_SIM_PROP(sms_data), record-1, SMS_PID(sms_data)); /* * send indication to MMI */ tl_message_ind_from_net (MEM_SM, record, SMS_SIM_PROP(sms_data).max_record, SMS_RP_RCVD(sms_data)); rl_report_req_ack (NULL); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); } else switch (sms_data->use_mem_b) // check alternative B { case DISPLAY: /* * Only display of the message */ tl_message_ind_from_net (NOT_PRESENT_8BIT, 0, 0, SMS_RP_RCVD(sms_data)); { if (sms_data->mhc NEQ SMS_MHC_PH2PLUS) { rl_report_req_ack (NULL); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); } } break; case MEM_ME: /* * memory type is mobile memory */ record = tl_get_free_space (MEM_ME); if (record) { /* * store in mobile memory */ /* Implements Measure#32: Row 104 */ if (pcm_WriteRecord ((UBYTE *)ef_sms_id, record, SIZE_EF_SMS, data) EQ PCM_OK) { /* * update status byte */ tl_store_status (&SMS_ME_PROP(sms_data), record-1, SMS_RECORD_REC_UNREAD); tl_store_pid (&SMS_ME_PROP(sms_data), record-1, SMS_PID(sms_data)); /* * send indication to MMI */ tl_message_ind_from_net (MEM_ME, record, SMS_ME_PROP(sms_data).max_record, SMS_RP_RCVD(sms_data)); /* * acknowledge to the infrastructure */ rl_report_req_ack (NULL); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); break; } } /*FALLTHROUGH*/ /*lint -fallthrough*/ default: if (tl_get_free_space (MEM_ME) OR tl_get_free_space (MEM_SM)) { /* * error to the infrastructure */ rl_report_req_error (SMS_RP_CS_PROTOCOL_ERROR, NULL); /* * RL_RELEASE_REQ ==> */ rl_release_req(SMS_INST.ti); } else { if (update_cnf->cause NEQ SIM_CAUSE_DRV_TEMPFAIL) { /* change mem_cap_avail flag on SIM and return error */ tl_sms_memo_exceeded (FALSE); } else { /* * RP_ERROR => */ rl_report_req_error ( SMS_RP_CS_PROTOCOL_ERROR, NULL); /* * RL_RELEASE_REQ ==> */ rl_release_req(SMS_INST.ti); } } tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_FREE); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); break; case IGNORE: rl_report_req_ack (NULL); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); MFREE (SMS_RP_RCVD(sms_data)); SMS_RP_RCVD(sms_data) = NULL; break; } sms_data->use_mem_b = NOTHING; MFREE (SMS_RP_RCVD(sms_data)); SMS_RP_RCVD(sms_data) = NULL; break; case NET_23430_WRITE: if (update_cnf->cause EQ SIM_NO_ERROR) { CCD_END; tl_sim_update_req (record, SMS_RECORD_FREE, NULL); tl_set_access_fifo (ACCESS_BY_NET); SET_STATE (STATE_NET, NET_23430_DELETE); return; } tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_FREE); tl_sms_memo_exceeded (FALSE); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); break; case NET_23430_DELETE: tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_FREE); rl_report_req_ack (NULL); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); break; default: assert (GET_STATE (STATE_NET) EQ NET_IDLE); /* illegal state */ // SET_STATE (STATE_NET, NET_IDLE); break; } CCD_END; SET_STATE (STATE_NET, NET_IDLE); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_sim_update_cnf | +--------------------------------------------------------------------+ PURPOSE : After updating of EF(SMSS) the Entity state is checked and a MNSMS_REPORT_IND is sent to indicate the Ready State */ GLOBAL void tl_sim_update_cnf (T_SIM_UPDATE_CNF *update_cnf) { GET_INSTANCE_DATA; UBYTE next_rec_num = 0; TRACE_FUNCTION ("tl_sim_update_cnf()"); sms_data->sms_sim_access_info[update_cnf->req_id].entry_used = FALSE; switch (tl_read_access_fifo ()) { case ACCESS_BY_MMI: if (sms_data->sms_sim_access_info[update_cnf->req_id].datafield EQ SIM_SMSS AND SMS_ENT_STATE(sms_data) EQ SMS_STATE_INITIALISING) { tl_mnsms_report_ind (SMS_ENT_STATE(sms_data) = SMS_STATE_READY); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); PFREE (update_cnf); return; } if (GET_STATE (STATE_MMI) EQ MMI_DELETE) { GET_MO_INSTANCE(sms_data); /* * confirm deletion to user */ if(SMS_REC_STATUS(sms_data) NEQ CMGD_DEL_INDEX) { /* Status value is given. Find the next record satisfying this status value */ next_rec_num = tl_search_record_for_delete (((SMS_SEL_MEM(sms_data) EQ MEM_ME)? &SMS_ME_PROP(sms_data):&SMS_SIM_PROP(sms_data)), SMS_SEL_REC(sms_data), SMS_REC_STATUS(sms_data)); } tl_mnsms_delete_cnf (SMS_SEL_MEM(sms_data), SMS_SEL_REC(sms_data), next_rec_num, SIM_NO_ERROR); SET_STATE (STATE_MMI, MMI_IDLE); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); } else if (GET_STATE (STATE_MMI) EQ MMI_RESUME) { /* * confirm resumption to user */ if (sms_data->pr_cntrl.save_cause EQ SMS_NO_ERROR) { if (update_cnf->cause == SIM_NO_ERROR) { tl_mnsms_resume_cnf(SMS_NO_ERROR); } else { tl_mnsms_resume_cnf(update_cnf->cause); } } else { tl_mnsms_resume_cnf(sms_data->pr_cntrl.save_cause); } SET_STATE (STATE_MMI, MMI_IDLE); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); } break; case ACCESS_BY_NET: TRACE_EVENT ("SIM_UPDATE_CNF ignored"); break; default: TRACE_ERROR ("Unexpected Error Value"); break; } #ifdef SIM_TOOLKIT if (sms_data->file_update_ind NEQ NULL) { T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind; sms_data->file_update_ind = NULL; tl_sim_file_update_ind (file_update_ind); } #endif PFREE (update_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_sim_update_record_cnf | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_UPDATE_RECORD_CNF. */ GLOBAL void tl_sim_update_record_cnf (T_SIM_UPDATE_RECORD_CNF *update_cnf) { GET_INSTANCE_DATA; TRACE_FUNCTION ("tl_sim_update_record_cnf()"); switch (tl_read_access_fifo ()) { case ACCESS_BY_NET: GET_MT_INSTANCE(sms_data); /* MT */ tl_sim_update_rec_cnf_net (update_cnf); break; case ACCESS_BY_MMI: GET_MO_INSTANCE(sms_data); /* MO */ tl_sim_update_rec_cnf_mmi (update_cnf); break; default: assert (0); /* impossible case */ break; } PFREE (update_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_sim_read_record_cnf | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_READ_RECORD_CNF. */ GLOBAL void tl_sim_read_record_cnf (T_SIM_READ_RECORD_CNF *read_cnf) { T_SIM_PDU *sim_pdu; GET_INSTANCE_DATA; UBYTE record; TRACE_FUNCTION ("tl_sim_read_record_cnf()"); record = sms_data->sms_sim_access_info[read_cnf->req_id].rec_num; sms_data->sms_sim_access_info[read_cnf->req_id].entry_used = FALSE; if (sms_data) /*lint !e774 always True*/ { switch (tl_read_access_fifo ()) { case ACCESS_BY_MMI: GET_MO_INSTANCE(sms_data); /* MO */ switch (GET_STATE (STATE_MMI)) { case MMI_READ: /* * read attempt from MMI */ if (read_cnf->cause EQ SIM_NO_ERROR AND record EQ SMS_SEL_REC(sms_data)) { tl_store_status (&SMS_SIM_PROP(sms_data), record-1, read_cnf->linear_data[0]); if (SMS_INST_GET_STATE (STATE_TL) EQ TL_SEND) { MCAST (cp_data, U_CP_DATA); MALLOC (sim_pdu, sizeof(T_SIM_PDU)); CCD_START; if (tl_modify_submit (sim_pdu, SMS_MODIFY(sms_data), SMS_SDU(sms_data), read_cnf->linear_data) AND tl_prepare_submit (sim_pdu, cp_data)) { /* * RL_DATA_REQ */ if (!rl_data_req (SMS_INST.tp_mr, cp_data)) { SMS_INST_SET_STATE (STATE_TL, TL_IDLE); /* * release connection */ rl_release_req(SMS_INST.ti); /* * send not successful but we confirm with no error ???!! */ tl_mnsms_submit_cnf (MEM_SM, record, NOT_PRESENT_8BIT, SMS_NO_ERROR, NULL); } } else { SMS_INST_SET_STATE (STATE_TL, TL_IDLE); tl_mnsms_submit_cnf (MEM_SM, record, NOT_PRESENT_8BIT, SMS_CAUSE_PARAM_WRONG, NULL); } CCD_END; MFREE (sim_pdu); MFREE (SMS_SDU(sms_data)); SMS_SDU(sms_data) = NULL; SET_STATE (STATE_MMI, MMI_IDLE); break; } if ((read_cnf->linear_data[0] & 1) EQ SMS_RECORD_FREE) { tl_mnsms_read_cnf (MEM_SM, 0, NULL, SMS_CAUSE_INV_INDEX); } else if (((read_cnf->linear_data[0] & 7) EQ SMS_RECORD_REC_UNREAD) AND SMS_READ_MODE(sms_data) NEQ READ_PREVIEW) { tl_set_access_fifo (ACCESS_BY_MMI); SET_STATE (STATE_MMI, MMI_READ_STATE_UPDATE); SMS_INST_SET_STATE (STATE_TL, TL_OTHER); tl_sim_update_req (record, SMS_RECORD_REC_READ, &read_cnf->linear_data[1]); if (SMS_READ_MODE(sms_data) NEQ READ_STATUS_CHANGE) { // read_cnf->linear_data[0] = SMS_RECORD_REC_READ; /* * keep read data until reception of UPDATE CONFIRM */ if (SMS_SIM_READ(sms_data) NEQ 0) PFREE(SMS_SIM_READ(sms_data)); SMS_SIM_READ(sms_data) = read_cnf; return; /* read_cnf not to be deallocated */ } PFREE (read_cnf); return; /* keep states */ } else { SMS_EM_READ_SHORT_MESSAGE_2; tl_mnsms_read_cnf (MEM_SM, record, ((SMS_READ_MODE(sms_data) EQ READ_STATUS_CHANGE)? NULL: read_cnf->linear_data), SIM_NO_ERROR); } } else { if (SMS_INST_GET_STATE (STATE_TL) EQ TL_SEND) { if (read_cnf->cause EQ SIM_NO_ERROR) tl_mnsms_submit_cnf (MEM_SM, record, NOT_PRESENT_8BIT, SMS_CAUSE_INV_INDEX, NULL); else tl_mnsms_submit_cnf (MEM_SM, record, NOT_PRESENT_8BIT, read_cnf->cause, NULL); } else tl_mnsms_read_cnf (MEM_SM, 0, NULL, SMS_CAUSE_INV_INDEX); } SET_STATE (STATE_MMI, MMI_IDLE); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); break; case MMI_FIND_FIRST: #ifdef SIM_TOOLKIT if (sms_data->file_update_ind NEQ NULL) { T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind; /* * Take a backup of the current status of the MMI_STATE */ sms_data->stored_mmi_state = GET_STATE(STATE_MMI); SET_STATE (STATE_MMI, MMI_IDLE); sms_data->file_update_ind = NULL; tl_sim_file_update_ind (file_update_ind); /* Implements Measure# 7 */ if( tl_sim_rd_record_update_state(read_cnf) ) return; } #endif /* * first record is scanned */ if (read_cnf->cause EQ SIM_NO_ERROR) { /* Store max. supported records of the SIM */ SMS_SIM_PROP(sms_data).max_record = read_cnf->max_record; if (SMS_SIM_PROP(sms_data).max_record > MAX_RECORD_SIM) { /* The number of supported records is limited by SMS */ SMS_SIM_PROP(sms_data).max_record = MAX_RECORD_SIM; } else if (SMS_SIM_PROP(sms_data).max_record EQ 0) { /* We have at least one record as we successfully read it * regardless of the returned value from the SIM */ SMS_SIM_PROP(sms_data).max_record = 1; } /* * continue with MMI_FIND_NEXT */ } else { /* * No EF_SMS field on the SIM. */ SMS_SIM_PROP(sms_data).max_record = 0; SET_STATE (STATE_MMI, MMI_IDLE); /* * init done */ tl_init_complete(); break; } /*FALLTHROUGH*/ /*lint -fallthrough*/ case MMI_FIND_NEXT: #ifdef SIM_TOOLKIT /* * Take a backup of the current status of the MMI_STATE */ sms_data->stored_mmi_state = GET_STATE(STATE_MMI); #endif /* SIM_TOOLKIT */ SET_STATE (STATE_MMI, MMI_IDLE); #ifdef SIM_TOOLKIT if (sms_data->file_update_ind NEQ NULL) { T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind; sms_data->file_update_ind = NULL; tl_sim_file_update_ind (file_update_ind); /* Implements Measure# 7 */ if( tl_sim_rd_record_update_state(read_cnf) ) return; } #endif /* * next record is scanned */ if (read_cnf->cause EQ SIM_NO_ERROR) { if (tl_find_status_pid (MEM_SM, record, read_cnf->linear_data, &SMS_SIM_PROP(sms_data))) tl_message_ind_from_sim (MEM_SM, record, read_cnf->max_record, read_cnf->linear_data); if (record < SMS_SIM_PROP(sms_data).max_record) tl_find_next (MEM_SM, (UBYTE)(record + 1)); else { #ifdef SIM_TOOLKIT if (sms_data->sim_mem_update) { PALLOC (file_update_res, SIM_FILE_UPDATE_RES); file_update_res->source = SRC_SMS; file_update_res->fu_rsc = SIM_FU_SUCCESS; PSENDX (SIM, file_update_res); sms_data->sim_mem_update = FALSE; } #endif /* * check for existing but empty memory */ if (SMS_SIM_PROP(sms_data).max_record > 0 AND !SMS_SIM_PROP(sms_data).any_valid) tl_message_ind_from_sim (MEM_SM, 0, SMS_SIM_PROP(sms_data).max_record, NULL); /* * init done */ tl_init_complete(); } } else { /* * declare only successful read * entries as available */ SMS_SIM_PROP(sms_data).max_record = record - 1; // must be doubled /* * init done */ tl_init_complete(); } break; default: assert (GET_STATE (STATE_MMI) EQ MMI_IDLE); /* illegal state */ break; } #ifdef SIM_TOOLKIT if (sms_data->file_update_ind NEQ NULL) { T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind; sms_data->file_update_ind = NULL; tl_sim_file_update_ind (file_update_ind); } #endif break; case ACCESS_BY_NET: GET_MT_INSTANCE(sms_data); /* MT */ switch (GET_STATE (STATE_NET)) { case NET_READ: if (tl_check_replace_entry (&SMS_RP_RCVD(sms_data)->rp_user_data.tpdu.b_tpdu[1], &read_cnf->linear_data[1])) { /* *record shall be replaced */ tl_sim_conv_update_req (record, SMS_RP_RCVD(sms_data)); SMS_EM_REPLACE_SMS_IN_SIM; tl_set_access_fifo (ACCESS_BY_NET); SET_STATE (STATE_NET, NET_WRITE); } else { int i; i = tl_check_mt_pid (&SMS_SIM_PROP(sms_data), record + 1, SMS_PID(sms_data)); if (i > 0) { tl_set_access_fifo (ACCESS_BY_NET); tl_sim_read_record_req((UBYTE)i); } else { MCAST (sms_deliver, TP_DELIVER); SET_STATE (STATE_NET, NET_IDLE); CCD_START; ccd_decodeMsg (CCDENT_SMS, DOWNLINK, (T_MSGBUF *)&SMS_RP_RCVD(sms_data)->rp_user_data.tpdu, (UBYTE *)sms_deliver, TP_DELIVER); tl_handle_message (sms_deliver); CCD_END; } } break; default: assert (GET_STATE (STATE_NET) EQ NET_IDLE); /* illegal state */ break; } break; default: assert (0); /* impossible case */ break; } } PFREE (read_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_sim_remove_ind | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_REMOVE_IND. */ GLOBAL void tl_sim_remove_ind (T_SIM_REMOVE_IND *remove_ind) { USHORT error; register T_SMS_DATA *sms_data = GET_SMS_INSTANCE (0); TRACE_FUNCTION ("tl_sim_remove_ind()"); if (sms_data) { error = (remove_ind->cause EQ SIM_NO_ERROR)? SMS_CAUSE_SIM_BUSY: remove_ind->cause; tl_sim_abort_to_mmi (error); sms_data->init_done = FALSE; SMS_SIM_PROP(sms_data).max_record = 0; sms_data->me_backup.max_record = 0; sms_data->sim_mem_update = FALSE; } PFREE (remove_ind); } #if defined(SIM_TOOLKIT) /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_sim_toolkit_cnf | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_TOOLKIT_CNF. */ GLOBAL void tl_sim_toolkit_cnf (T_SIM_TOOLKIT_CNF *toolkit_cnf) { GET_INSTANCE_DATA; TRACE_FUNCTION ("tl_sim_toolkit_cnf()"); switch (tl_read_access_fifo ()) { case ACCESS_BY_NET: GET_MT_INSTANCE(sms_data); /* MT */ tl_sim_toolkit_confirm (toolkit_cnf); break; default: assert(0); break; } PFREE (toolkit_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_sim_file_update_ind | +--------------------------------------------------------------------+ PURPOSE : Process the primitive SIM_FILE_UPDATE_IND. */ GLOBAL void tl_sim_file_update_ind (T_SIM_FILE_UPDATE_IND *file_update_ind) { USHORT i; BOOL found_sms = FALSE; /* short messages changed by SAT */ BOOL found_smss = FALSE; /* short message status changed by SAT */ register T_SMS_DATA *sms_data = GET_SMS_INSTANCE (0); TRACE_FUNCTION ("tl_sim_file_update_ind()"); if (sms_data) { /* * avoid interference with active MMI procedure */ switch (GET_STATE (STATE_MMI)) { case MMI_IDLE: break; default: if (sms_data->file_update_ind NEQ NULL) PFREE (sms_data->file_update_ind); /* store primitive for delayed reaction */ sms_data->file_update_ind = file_update_ind; return; } for (i = 0; i < file_update_ind->val_nr; i++) { if((file_update_ind->file_info[i].v_path_info EQ TRUE) AND (file_update_ind->file_info[i].path_info.df_level1 EQ SIM_DF_TELECOM) AND (file_update_ind->file_info[i].path_info.v_df_level2 EQ FALSE)) { if (file_update_ind->file_info[i].datafield EQ SIM_SMS) { /* short messages changed by SAT */ found_sms = TRUE; sms_data->sim_mem_update = TRUE; } else if (file_update_ind->file_info[i].datafield EQ SIM_SMSS) { /* short message status changed by SAT */ found_smss = TRUE; } } if (found_sms AND found_smss) break; } if (found_smss) { /* short message status changed by SAT */ tl_sim_read_req (SIM_SMSS, 2); sms_data->sim_mem_update = found_sms NEQ FALSE; SET_STATE (STATE_MMI, MMI_STATE_UPDATE); } else if (found_sms) { /* short messages changed by SAT */ sms_data->init_done = FALSE; SMS_SIM_PROP(sms_data).max_record = 0; tl_mnsms_report_ind (SMS_ENT_STATE(sms_data) = SMS_STATE_INITIALISING); sms_data->sim_mem_update = TRUE; tl_find_first (MEM_SM); } else { /* Nothing to do, indicate success to SAT */ PALLOC (file_update_res, SIM_FILE_UPDATE_RES); /* T_SIM_FILE_UPDATE_RES */ file_update_res->source = SRC_SMS; file_update_res->fu_rsc = SIM_FU_SUCCESS; PSENDX (SIM, file_update_res); } } PFREE (file_update_ind); } #endif // SIM_TOOLKIT /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLF | | STATE : code ROUTINE : tl_mnsms_cmms_end_ind | +--------------------------------------------------------------------+ PURPOSE : Function used for sending MNSMS_REPORT_IND.Primitive to ACI when cmms_mode is eqaul to 1. */ GLOBAL void tl_mnsms_cmms_end_ind(void) { GET_INSTANCE_DATA; PALLOC (report_ind, MNSMS_REPORT_IND); TRACE_FUNCTION ("tl_mnsms_cmms_end_ind()"); if(sms_data->cmms_mode EQ CMMS_MODE_ONE) { sms_data->cmms_mode = CMMS_MODE_DEF; report_ind->state = SMS_STATE_READY; report_ind->v_cmms_mode = TRUE; report_ind->cmms_mode = sms_data->cmms_mode; PSENDX (MMI, report_ind); } } #ifdef SIM_PERS_OTA /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_OTA_message_res | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MNSMS_OTA_MESSAGE_RES. */ GLOBAL void tl_mnsms_OTA_message_res ( T_MNSMS_OTA_MESSAGE_RES *mnsms_OTA_message_res ) { T_SMS_DATA *sms_data = GET_INSTANCE(0); TRACE_FUNCTION ("tl_mnsms_OTA_message_res()"); if (sms_data) /*lint !e774 always True*/ { GET_MT_INSTANCE(sms_data); /* MT operation */ switch (SMS_INST_GET_STATE (STATE_TL)) { case TL_RECEIVE: if (sms_timer_check(TR2M)) { T_TP_DLVR_REP_ACK *rep_ack ; T_rp_user_data *rp_ud; MALLOC(rep_ack, sizeof(T_TP_DLVR_REP_ACK)); MALLOC(rp_ud, sizeof(T_rp_user_data)); rep_ack->tp_vt_mti = SMS_VT_DLVR_REP_ACK; rep_ack->tp_udhi = SMS_UDHI_NOT_INCLUDED; rep_ack->tp_mti = SMS_DELIVER_REPORT; rep_ack->v_tp_udh_inc = FALSE; memcpy(rep_ack->tp_ud.data, mnsms_OTA_message_res->data,mnsms_OTA_message_res->len); rep_ack->tp_ud.c_data =mnsms_OTA_message_res->len; //No of octets rep_ack->tp_ud.length = mnsms_OTA_message_res->packedlen; /*Since default alphabet is used as per 23.040 sec. 9.2.3.16 the length contains no of septets of data returned */ rep_ack->tp_ext = SMS_EXT_NOT_INCLUDED; rep_ack->v_tp_ud = TRUE; rep_ack->tp_udl_p = SMS_UD_INCLUDED; rep_ack->tp_dcs = mnsms_OTA_message_res->tp_dcs; rep_ack->v_tp_dcs = TRUE; rep_ack->tp_dcs_p = SMS_DCS_INCLUDED; rep_ack->tp_pid = mnsms_OTA_message_res->tp_pid; rep_ack->v_tp_pid = TRUE; rep_ack->tp_pid_p = SMS_PID_INCLUDED; rp_ud->tpdu.o_tpdu = 0; rp_ud->tpdu.l_tpdu = TPDU_BIT_LEN; rp_ud->v_tpdu = (ccd_codeMsg (CCDENT_SMS, UPLINK, (T_MSGBUF *)&rp_ud->tpdu, (UBYTE *)rep_ack, SMS_VT_DLVR_REP_ACK) EQ ccdOK); rp_ud->tp_mti = SMS_DELIVER_REPORT; MFREE (rep_ack); rl_report_req_ack (rp_ud); MFREE (rp_ud); SMS_INST_SET_STATE (STATE_TL, TL_IDLE); } else { /*TR2M TIM EXPIRE -ACI NOT RESPONDED WITHIN TR2M */ } break; default: /* INVALID SMS TL STATE IN MNSMS_OTA_MESSAGE_RES */ break; } } PFREE (mnsms_OTA_message_res); } #endif /* End OTA */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_retrans_req | +--------------------------------------------------------------------+ PURPOSE : Handles the primitive MNSMS_RETRANS_REQ. This will support user requested retransmission of the last failed message as per 23.040 R99 Section 9.2.3.6. */ #ifdef REL99 GLOBAL void tl_mnsms_retrans_req (T_MNSMS_RETRANS_REQ *mnsms_retrans_req) { GET_INSTANCE_DATA; TRACE_FUNCTION ("tl_mnsms_retrans_req()"); switch (SMS_INST_GET_STATE (STATE_TL)) { case TL_SEND_CONTD: /* * stop timer TLCT */ sms_timer_stop(TLCT); /*FALLTHROUGH*/ /*lint -fallthrough*/ case TL_IDLE: if (sms_timer_check(TRAM)) { /* * MNSMS_SUBMIT_CNF */ tl_mnsms_retrans_cnf (SMS_SEL_MEM(sms_data), SMS_SEL_REC(sms_data), NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL); break; } /* Check if MO message is present(stored CPDU data available?) */ if (SMS_DATA_REQ(sms_data) NEQ NULL) { if(mnsms_retrans_req->auto_rep_flag EQ AUTO_REP_FLAG_ENABLED) { SMS_INST.tl_retx = 0; } else { /* Set to the max value so that retransmission will not be done */ SMS_INST.tl_retx = TL_MAX_RETANS; } SMS_INST_SET_STATE (STATE_TL, TL_SEND); /* Restore the record number and storage type */ SMS_SEL_REC(sms_data) = SMS_INST.failed_msg_rec_num; SMS_SEL_MEM(sms_data) = SMS_INST.failed_msg_mem; SMS_INST.failed_msg_retx = TRUE; /* * TL state transition TL_ESTABLISH * EST state transition EST_SEND */ SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH); SET_STATE (STATE_EST, EST_RTX); /* * establish connection */ tl_establish_connection(FALSE); } else { tl_mnsms_retrans_cnf (SMS_SEL_MEM(sms_data),SMS_SEL_REC(sms_data), SMS_TP_REF_RET(sms_data), SMS_CAUSE_FAILED_MSG_NOT_FOUND, NULL); } break; default: tl_mnsms_retrans_cnf (SMS_SEL_MEM(sms_data),SMS_SEL_REC(sms_data), SMS_TP_REF_RET(sms_data), SMS_CAUSE_ENTITY_BUSY, NULL); break; } PFREE(mnsms_retrans_req); return; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_retrans_cnf | +--------------------------------------------------------------------+ PURPOSE : Generate a response to the primitive MNSMS_RETRANS_REQ. */ GLOBAL void tl_mnsms_retrans_cnf ( UBYTE mem_type, UBYTE record, UBYTE tp_mr, USHORT cause, T_sms_sdu *sms_sdu ) { TRACE_FUNCTION ("tl_mnsms_retrans_cnf()"); { PALLOC (retrans_cnf, MNSMS_RETRANS_CNF); retrans_cnf->mem_type = mem_type; retrans_cnf->rec_num = record; retrans_cnf->tp_mr = tp_mr; retrans_cnf->cause = cause; if (sms_sdu NEQ NULL) { memcpy (&retrans_cnf->sms_sdu, sms_sdu, sizeof (T_sms_sdu)); } else { memset (&retrans_cnf->sms_sdu, 0, sizeof (T_sms_sdu)); } PSENDX (MMI, retrans_cnf); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_TLP | | STATE : code ROUTINE : tl_mnsms_send_prog_ind | +--------------------------------------------------------------------+ PURPOSE : Send the primitive MNSMS_SEND_PROG_IND. */ GLOBAL void tl_mnsms_send_prog_ind (void) { GET_INSTANCE_DATA; TRACE_FUNCTION ("tl_mnsms_send_prog_ind ()"); { PALLOC (send_prog_ind, MNSMS_SEND_PROG_IND); send_prog_ind->resend_count = sms_data->data[INST_MO].tl_retx; send_prog_ind->max_retrans = TL_MAX_RETANS; PSENDX (MMI, send_prog_ind); } } #endif /* REL99 */ #endif