FreeCalypso > hg > fc-tourmaline
view src/g23m-gsm/sms/sms_rl.c @ 303:f76436d19a7a default tip
!GPRS config: fix long-standing AT+COPS chance hanging bug
There has been a long-standing bug in FreeCalypso going back years:
sometimes in the AT command bring-up sequence of an ACI-only MS,
the AT+COPS command would produce only a power scan followed by
cessation of protocol stack activity (only L1 ADC traces), instead
of the expected network search sequence. This behaviour was seen
in different FC firmware versions going back to Citrine, and seemed
to follow some law of chance, not reliably repeatable.
This bug has been tracked down and found to be specific to !GPRS
configuration, stemming from our TCS2/TCS3 hybrid and reconstruction
of !GPRS support that was bitrotten in TCS3.2/LoCosto version.
ACI module psa_mms.c, needed only for !GPRS, was missing in the TCS3
version and had to be pulled from TCS2 - but as it turns out,
there is a new field in the MMR_REG_REQ primitive that needs to be
set correctly, and that psa_mms.c module is the place where this
initialization needed to be added.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 08 Jun 2023 08:23:37 +0000 |
parents | fa8dc04885d8 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : GSM-F&D (8411) | Modul : SMS_RL +----------------------------------------------------------------------------- | 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 relay layer | of the component SMS. +----------------------------------------------------------------------------- */ #ifndef SMS_RL_C #define SMS_RL_C #define ENTITY_SMS /*==== INCLUDES ===================================================*/ #define SAP_RR /* get RR causes until all causes are in one document */ #define SAP_MMCM /* same reason */ #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 "sms_em.h" /*==== EXPORT ======================================================*/ /*==== PRIVAT ======================================================*/ /*==== VARIABLES ===================================================*/ /*==== FUNCTIONS ===================================================*/ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_init | +--------------------------------------------------------------------+ PURPOSE : Initialize the relay layer. */ GLOBAL void rl_init (void) { GET_INSTANCE_DATA; TRACE_FUNCTION ("rl_init()"); sms_data->data[0].state[STATE_RL] = RL_IDLE; sms_data->data[1].state[STATE_RL] = RL_IDLE; } /*---- SIGNALS -----------------------------------------------------*/ #ifdef GPRS GLOBAL void rl_proceed (void) { GET_INSTANCE_DATA; TRACE_FUNCTION ("rl_proceed()"); if (SMS_INST_GET_STATE (STATE_RL) EQ RL_WAIT_FOR_SEND_ERROR) { SMS_INST_SET_STATE (STATE_RL, RL_IDLE); tl_report_ind (NULL, CAUSE_MAKE(DEFBY_STD, ORIGSIDE_MS, SMSRP_ORIGINATING_ENTITY, SMS_RP_CS_PROTOCOL_ERROR)); } } #endif /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_data_ind | +--------------------------------------------------------------------+ PURPOSE : Processing the signal RL_DATA_IND. */ GLOBAL void rl_data_ind (T_cp_user_data_dl *cp_user_data_dl) { GET_INSTANCE_DATA; TRACE_FUNCTION ("rl_data_ind()"); if (sms_data) { if (cp_user_data_dl->rp_mti EQ RP_ERROR_DL) TRACE_EVENT_P1 ("RP_ERROR.CAUSE rcvd: 0x%2.2X", (int)cp_user_data_dl->rp_error.rp_cause.rp_cause_value); switch (SMS_INST_GET_STATE (STATE_RL)) { /* ------------------------------------- */ case RL_ESTABLISHED: /* ------------------------------------- */ case RL_IDLE: /* ------------------------------------- */ { SMS_RP_REF(sms_data) = cp_user_data_dl->reference; if (cp_user_data_dl->rp_mti EQ RP_DATA_DL) { /* * RL state transition RL_WAIT_FOR_SEND_ACK */ SMS_INST_SET_STATE (STATE_RL, RL_WAIT_FOR_SEND_ACK); /* * start timer TR2M */ sms_timer_start(TR2M); SMS_EM_RECEIVE_RP_DATA; /* * TL_DATA_IND => */ tl_data_ind (&cp_user_data_dl->rp_data_dl); } else { MCAST (cp_data, U_CP_DATA); /* * If Message Id is unknwon then send RP-ERROR with cause #97 */ if(cp_user_data_dl->rp_mti > 0x06) { rl_build_rp_error (cp_user_data_dl->reference, SMS_RP_CS_MSG_NON_EXIST, cp_data, NULL); } else { rl_build_rp_error (cp_user_data_dl->reference, SMS_RP_CS_MSG_NOT_COMP, cp_data, NULL); } SMS_EM_SEND_RP_ERROR; cp_data_req (cp_data); /* * CP_RELEASE_REQ => */ TRACE_EVENT("CP_RELEASE_REQ_1"); cp_release_req (SMS_INST.ti); /* * free instance */ FREE_SMS_INSTANCE (SMS_INST.ti); } break; } /* ------------------------------------- */ case RL_WAIT_FOR_ACK: /* ------------------------------------- */ TRACE_FUNCTION ("rl_data_ind(): RP_WAIT_FOR_ACK"); switch (cp_user_data_dl->rp_mti) { case RP_ACK_DL: TRACE_FUNCTION ("rl_data_ind(): RP_ACK_DL"); /* * stop timer TR1M */ sms_timer_stop(TR1M); /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); /* * if CMMS mode is 1 or 2 then only make cmm_release_pending TRUE */ if(CMMS_ACTIVE) { sms_data->cmms_release_pending = TRUE; } /* * TL_REPORT_IND => */ tl_report_ind (((cp_user_data_dl->rp_ack.v_rp_user_data)? &cp_user_data_dl->rp_ack.rp_user_data: NULL), SMS_NO_ERROR); /* Since the transmission is successful, the data stored for retransmission can be freed */ if (SMS_DATA_REQ(sms_data) NEQ NULL) { PFREE (SMS_DATA_REQ(sms_data)); SMS_DATA_REQ(sms_data) = NULL; } SMS_EM_RECEIVE_RP_AKNOWLEDGE; break; case RP_ERROR_DL: /* When an RP-error with appropriate case value is * is received, Retransmission of SMS is started */ { #ifdef REL99 BOOL retrans_flag = FALSE; #endif TRACE_FUNCTION ("rl_data_ind(): RP_ERROR_DL"); /* * stop timer TR1M */ sms_timer_stop(TR1M); /* * if CMMS mode is 1 or 2 then only make cmm_release_pending TRUE */ if(CMMS_ACTIVE) { sms_data->cmms_release_pending = TRUE; } #ifdef REL99 /* * This is done for Retransmission for the causes * listed in the table 8.4/3gPP TS 24.011(Part 1) */ if (SMS_INST.tl_retx < TL_MAX_RETANS) { /* Check whether the cause value satisfies the one for retransmission * listed in the table 8.4/3gPP TS 24.011(Part 1) */ switch(cp_user_data_dl->rp_error.rp_cause.rp_cause_value) { case SMS_RP_CS_UNASSIGNED_NUMBER: case SMS_RP_CS_OPERATOR_DET_BARRED: case SMS_RP_CS_CALL_BARRED: case SMS_RP_CS_SM_TRANSFER_REJECTED: case SMS_RP_CS_MEM_CAP_EXCEEDED: case SMS_RP_CS_UNIDENT_SUBSCRIBER: case SMS_RP_CS_FACILITY_REJECTED: case SMS_RP_CS_UNKNOWN_SUBSCRIBER: case SMS_RP_CS_NET_OUT_OF_ORDER: case SMS_RP_CS_NO_RESOURCES: case SMS_RP_CS_FAC_NOT_SUBSCRIBED: case SMS_RP_CS_FAC_NOT_IMPL: case SMS_RP_CS_INV_SM_TR_REF_VAL: case SMS_RP_CS_SEM_INC_MSG: case SMS_RP_CS_INV_MAND_INFO: case SMS_RP_CS_MSG_NON_EXIST: case SMS_RP_CS_INFO_NON_EXIST: case SMS_RP_CS_PROTOCOL_ERROR: case SMS_RP_CS_INTERWORKING: retrans_flag = FALSE; break; /* All values other than the ones above are treated as temporary failures. This includes SMS_RP_CS_DEST_OUT_OF_ORDER, SMS_RP_CS_TEMP_FAILURE, SMS_RP_CS_CONGESTION, SMS_RP_CS_MSG_NOT_COMP and others non-standard values are taken as temporary error */ default: retrans_flag = TRUE; break; } } if(retrans_flag EQ TRUE) { TRACE_EVENT ("Retransmission cause received"); cp_release_req(SMS_INST.ti); TIMERSTART (SMS_INST_TR1M, 20000); TRACE_EVENT ("Delay expiry TR1M, retransmit"); } else #endif { /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); tl_report_ind (((cp_user_data_dl->rp_error.v_rp_user_data)? &cp_user_data_dl->rp_error.rp_user_data: NULL), CAUSE_MAKE(DEFBY_STD, ORIGSIDE_NET, SMSRP_ORIGINATING_ENTITY, cp_user_data_dl->rp_error.rp_cause.rp_cause_value)); SMS_EM_RECEIVE_RP_ERROR; } } break; default: TRACE_FUNCTION ("rl_data_ind(): default"); /* * stop timer TR1M */ sms_timer_stop(TR1M); { MCAST (cp_data_ul, U_CP_DATA); /* * If Message Id is unknwon then send RP-ERROR with cause #97 */ if(cp_user_data_dl->rp_mti > 0x06) { rl_build_rp_error (cp_user_data_dl->reference, SMS_RP_CS_MSG_NON_EXIST, cp_data_ul, NULL); } else { rl_build_rp_error (cp_user_data_dl->reference, SMS_RP_CS_PROTOCOL_ERROR, cp_data_ul, NULL); } cp_data_req (cp_data_ul); } #ifdef GPRS /* interworking from flow control */ if (SMS_LLC_FLOW(sms_data) NEQ SMS_LLC_BUSY_WAITING) #endif { SMS_INST_SET_STATE (STATE_RL, RL_IDLE); /* * if CMMS mode is 1 or 2 and current link used is GSM then only * make cmm_release_pending TRUE */ #ifdef GPRS if(CMMS_ACTIVE AND (SMS_INST.downlink EQ SMS_DOWNLINK_MMSMS)) { sms_data->cmms_release_pending = TRUE; } #endif /* * TL_REPORT_IND => */ /* * If Message Id is unknwon then send TL REPORT IND with cause #97 */ if(cp_user_data_dl->rp_mti > 0x06) { tl_report_ind (NULL, CAUSE_MAKE(DEFBY_STD, ORIGSIDE_MS, SMSRP_ORIGINATING_ENTITY, SMS_RP_CS_MSG_NON_EXIST)); } else { tl_report_ind (NULL, CAUSE_MAKE(DEFBY_STD, ORIGSIDE_MS, SMSRP_ORIGINATING_ENTITY, SMS_RP_CS_PROTOCOL_ERROR)); } } #ifdef GPRS else { SMS_INST_SET_STATE (STATE_RL, RL_WAIT_FOR_SEND_ERROR); } #endif SMS_EM_RECEIVE_UNKNOWN_2; break; } break; case RL_WAIT_FOR_SEND_ACK: TRACE_FUNCTION ("rl_data_ind(): RP_WAIT_FOR_SEND_ACK"); { MCAST (cp_data_ul, U_CP_DATA); /* * If Message Id is unknwon then send RP-ERROR with cause #97 */ if(cp_user_data_dl->rp_mti > 0x06) { rl_build_rp_error (cp_user_data_dl->reference, SMS_RP_CS_MSG_NON_EXIST, cp_data_ul, NULL); } else { rl_build_rp_error (cp_user_data_dl->reference, SMS_RP_CS_PROTOCOL_ERROR, cp_data_ul, NULL); } cp_data_req (cp_data_ul); } break; /* ------------------------------------- */ case RL_WAIT_FOR_SMMA_ACK: /* ------------------------------------- */ TRACE_FUNCTION ("rl_data_ind(): RP_WAIT_FOR_SMMA_ACK"); switch (cp_user_data_dl->rp_mti) { case RP_ACK_DL: TRACE_FUNCTION ("rl_data_ind(): RP_ACK_DL"); /* * stop timer TR1M */ sms_timer_stop(TR1M); SMS_INST.retrans = FALSE; /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); /* * TL_REPORT_IND => */ tl_report_ind (NULL, SMS_NO_ERROR); break; case RP_ERROR_DL: TRACE_FUNCTION ("rl_data_ind(): RP_ERROR_DL"); if (rl_temp_failure (cp_user_data_dl->rp_error. rp_cause.rp_cause_value)) { if (SMS_INST.retrans) { /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); SMS_INST.retrans = FALSE; /* * TL_REPORT_IND => */ tl_report_ind (NULL, CAUSE_MAKE(DEFBY_STD, ORIGSIDE_NET, SMSRP_ORIGINATING_ENTITY, cp_user_data_dl->rp_error.rp_cause.rp_cause_value)); sms_timer_stop(TR1M); tl_sms_memo_exceeded (TRUE); /* * stop timer TR1M */ } else { SMS_INST.retrans = TRUE; /* * RL state transition RL_WAIT_FOR_RETRANS_TIMER */ SMS_INST_SET_STATE (STATE_RL, RL_WAIT_FOR_RETRANS_TIMER); /* * stop timer TR1M */ sms_timer_stop(TR1M); /* * start timer TRAM */ sms_timer_start(TRAM); /* * CP_RELEASE_REQ => */ TRACE_EVENT("CP_RELEASE_REQ_11"); cp_release_req (SMS_INST.ti); } } else { /* * stop timer TR1M */ sms_timer_stop(TR1M); SMS_INST.retrans = FALSE; /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); /* * TL_REPORT_IND => */ tl_report_ind (NULL, CAUSE_MAKE(DEFBY_STD, ORIGSIDE_NET, SMSRP_ORIGINATING_ENTITY, cp_user_data_dl->rp_error.rp_cause.rp_cause_value)); tl_sms_memo_exceeded (TRUE); } break; default: TRACE_FUNCTION ("rl_data_ind(): default"); /* * stop timer TR1M */ sms_timer_stop(TR1M); SMS_INST.retrans = FALSE; /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); /* * If Message Id is unknwon then send RP-ERROR with cause #97 */ if(cp_user_data_dl->rp_mti > 0x06) { MCAST (cp_data, U_CP_DATA); rl_build_rp_error (cp_user_data_dl->reference, SMS_RP_CS_MSG_NON_EXIST, cp_data, NULL); SMS_EM_SEND_RP_ERROR; cp_data_req (cp_data); tl_report_ind (NULL, CAUSE_MAKE(DEFBY_STD, ORIGSIDE_MS, SMSRP_ORIGINATING_ENTITY, SMS_RP_CS_MSG_NON_EXIST)); } break; } break; } } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_establish_req | +--------------------------------------------------------------------+ PURPOSE : Processing the signal RL_ESTABLISH_REQ. */ GLOBAL void rl_establish_req (UBYTE ti) { GET_INSTANCE_DATA; TRACE_FUNCTION_P1 ("rl_establish_req(TI=%u)", ti); switch (SMS_INST_GET_STATE (STATE_RL)) { case RL_IDLE: /* * RL state transition RL_ESTABLISH */ SMS_INST_SET_STATE (STATE_RL, RL_ESTABLISH); /* * CP_ESTABLISH_REQ => */ cp_establish_req(ti); /* * start timer TR1M */ sms_data->timer_ti = ti; sms_timer_start(TR1M); break; default: TRACE_ERROR("RL_ESTABLISH_REQ in wrong state received!"); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_establish_cnf | +--------------------------------------------------------------------+ PURPOSE : Processing the signal RL_ESTABLISH_CNF. */ GLOBAL void rl_establish_cnf (BOOL success) { GET_INSTANCE_DATA; TRACE_FUNCTION ("rl_establish_cnf()"); switch (SMS_INST_GET_STATE (STATE_RL)) { case RL_ESTABLISH: /* * stop timer TR1M */ sms_timer_stop(TR1M); if (success EQ TRUE) { /* * RL state transition RL_ESTABLISHED */ SMS_INST_SET_STATE (STATE_RL, RL_ESTABLISHED); } else { /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); } /* * TL_ESTABLISH_CNF => */ tl_establish_cnf(success); break; default: TRACE_ERROR("RL_ESTABLISH_CNF in wrong state received!"); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_release_req | +--------------------------------------------------------------------+ PURPOSE : Processing the signal RL_RELEASE_REQ. */ GLOBAL void rl_release_req ( UBYTE ti) { TRACE_FUNCTION_P1 ("rl_release_req(TI=%u)", ti); /* * CP_RELEASE_REQ => */ TRACE_EVENT("CP_RELEASE_REQ_13"); cp_release_req(ti); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_data_req | +--------------------------------------------------------------------+ PURPOSE : Processing the signal RL_DATA_REQ. */ GLOBAL BOOL rl_data_req (UBYTE msg_ref, T_U_CP_DATA *cp_data) { GET_INSTANCE_DATA; TRACE_FUNCTION ("rl_data_req()"); if (sms_data) { switch (SMS_INST_GET_STATE (STATE_RL)) { case RL_ESTABLISHED: { SMS_INST.msg_ref = msg_ref; /* * RL state transtion RL_WAIT_FOR_ACK */ SMS_INST_SET_STATE (STATE_RL, RL_WAIT_FOR_ACK); SMS_EM_SEND_RP_DATA; cp_data->cp_user_data_ul.rp_mti = RP_DATA_UL; cp_data->cp_user_data_ul.reference = msg_ref; /* * CP_DATA_REQ => */ cp_data_req (cp_data); /* * start timer TR1M */ sms_timer_start(TR1M); return TRUE; } default: TRACE_ERROR("RL_DATA_REQ in wrong state received!"); break; } } return FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_error_ind | +--------------------------------------------------------------------+ PURPOSE : Processing the signal RL_ERROR_IND. */ GLOBAL void rl_error_ind (USHORT cause) { GET_INSTANCE_DATA; TRACE_FUNCTION ("rl_error_ind()"); if (sms_data) { switch (SMS_INST_GET_STATE (STATE_RL)) { /* --------------------------------- */ case RL_ESTABLISH: /* --------------------------------- */ if ( SMS_INST.tl_retx < TL_MAX_RETANS ) { switch ( cause ) { case MMCM_MMCS_MESSAGE_INCOMPAT: case RRCS_NORM: /* * start timer TR1M with value */ TIMERSTART ( SMS_INST_TR1M, 20000 ); TRACE_EVENT ( "Delay expiry TR1M, retransmit" ); return; default: /* No retransmission */ break; } } /* * stop timer TR1M */ sms_timer_stop(TR1M); /*FALLTHROUGH*/ /*lint -fallthrough*/ /* --------------------------------- */ case RL_ESTABLISHED: /* --------------------------------- */ /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); /* * free instance */ FREE_SMS_INSTANCE (SMS_INST.ti); /* * TL_REPORT_IND */ tl_report_ind (NULL, cause); break; /* --------------------------------- */ case RL_WAIT_FOR_ACK: /* --------------------------------- */ TRACE_FUNCTION ("rl_error_ind(): RL_WAIT_FOR_ACK"); /* * The following code is to implement a subset of * 3GPP 23.040 Release 1999 subclause 9.2.3.6. * For certain errors the SMS SUBMIT / SMS COMMAND is repeated * after timeout of TR1M. */ TRACE_EVENT_P2 ("TL retrans #%d, error_cs %04x", SMS_INST.tl_retx, cause); if (SMS_INST.tl_retx < TL_MAX_RETANS) { switch (cause) { case SMS_CAUSE_NET_TIMEOUT: /* 11.10 test case 34.2.2 step 68 */ /* * start timer TR1M with value */ TIMERSTART (SMS_INST_TR1M, 20000); TRACE_EVENT ("Delay expiry TR1M, retransmit"); return; case RRCS_NORM: case MMCM_MMCS_MESSAGE_INCOMPAT: /* Make cingular happy, #19189 */ TRACE_EVENT ("Retransmission after TR1M"); return; default: /* No retransmission */ break; } } /* * stop timer TR1M */ sms_timer_stop(TR1M); /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); /* * free instance */ FREE_SMS_INSTANCE (SMS_INST.ti); /* * TL_REPORT_IND => */ tl_report_ind (NULL, cause); break; /* --------------------------------- */ case RL_WAIT_FOR_SEND_ACK: /* --------------------------------- */ TRACE_FUNCTION ("rl_error_ind(): RL_WAIT_FOR_SEND_ACK"); /* * free instance */ FREE_SMS_INSTANCE (SMS_INST.ti); /* * stop timer TR2M */ sms_timer_stop(TR2M); /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); /* * TL_REPORT_IND => */ tl_report_ind (NULL, cause); break; /* --------------------------------- */ case RL_WAIT_FOR_SMMA_ACK: /* --------------------------------- */ TRACE_FUNCTION ("rl_error_ind(): RL_WAIT_FOR_SMMA_ACK"); // FREE_SMS_INSTANCE (SMS_INST.ti); if (SMS_INST.retrans) { /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); SMS_INST.retrans = FALSE; /* * TL_REPORT_IND => */ tl_report_ind (NULL, SMS_CAUSE_NET_TIMEOUT); /* * stop timer TR1M */ sms_timer_stop(TR1M); tl_sms_memo_exceeded (TRUE); } else { SMS_INST.retrans = TRUE; /* * RL state transition RL_WAIT_FOR_RETRANS_TIMER */ SMS_INST_SET_STATE (STATE_RL, RL_WAIT_FOR_RETRANS_TIMER); /* * stop timer TR1M */ sms_timer_stop(TR1M); /* * start timer TRAM */ sms_timer_start(TRAM); /* * CP_RELEASE_REQ => */ TRACE_EVENT("CP_RELEASE_REQ_15"); cp_release_req (SMS_INST.ti); /* * free instance */ FREE_SMS_INSTANCE (SMS_INST.ti); } break; default: if(CMMS_ACTIVE) { tl_cmms_end(); } /* * free instance */ FREE_SMS_INSTANCE (SMS_INST.ti); /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); break; } } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_mem_avail_req | +--------------------------------------------------------------------+ PURPOSE : Processing the signal RL_MEM_AVAIL_REQ. */ GLOBAL BOOL rl_mem_avail_req (void) { GET_INSTANCE_DATA; TRACE_FUNCTION ("rl_mem_avail_req()"); if (sms_data) { switch (SMS_INST_GET_STATE (STATE_RL)) { case RL_ESTABLISHED: { CCD_START; { MCAST (cp_data, U_CP_DATA); /* * RL state transition RL_WAIT_FOR_SMMA_ACK */ SMS_INST_SET_STATE (STATE_RL, RL_WAIT_FOR_SMMA_ACK); SMS_RP_REF(sms_data) = SMS_INST.tp_mr; rl_build_rp_smma (SMS_RP_REF(sms_data), cp_data); CCD_END; /* * CP_DATA_REQ => */ cp_data_req (cp_data); } /* * start timer TR1M */ sms_timer_start(TR1M); return TRUE; default: TRACE_ERROR("RL_MEM_AVAIL_REQ in wrong state received!"); break; } } } return FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_start_tram_req | +--------------------------------------------------------------------+ PURPOSE : Processing the signal RL_START_TRAM_REQ. */ GLOBAL void rl_start_tram_req (void) { GET_INSTANCE_DATA; TRACE_FUNCTION ("rl_start_tram_req()"); SMS_INST.retrans = TRUE; /* * RL state transition RL_WAIT_FOR_RETRANS_TIMER */ SMS_INST_SET_STATE (STATE_RL, RL_WAIT_FOR_RETRANS_TIMER); /* * start timer TRAM */ sms_timer_start(TRAM); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_build_rp_ack | +--------------------------------------------------------------------+ PURPOSE : Processing the function RL_BUILD_RP_ACK. */ LOCAL void rl_build_rp_ack (UBYTE msg_ref, T_U_CP_DATA *cp_data, T_rp_user_data *rp_user_data) { TRACE_FUNCTION ("rl_build_rp_ack()"); memset (&cp_data->cp_user_data_ul.rp_ack, 0, sizeof (T_rp_ack)); cp_data->msg_type = U_CP_DATA; cp_data->cp_user_data_ul.rp_mti = RP_ACK_UL; cp_data->cp_user_data_ul.reference = msg_ref; cp_data->cp_user_data_ul.v_rp_data_ul = FALSE; cp_data->cp_user_data_ul.v_rp_error = FALSE; cp_data->cp_user_data_ul.v_rp_ack = TRUE; if (rp_user_data NEQ NULL AND rp_user_data->v_tpdu) { memcpy (&cp_data->cp_user_data_ul.rp_ack.rp_user_data, rp_user_data, sizeof (T_rp_user_data)); cp_data->cp_user_data_ul.rp_ack.v_rp_user_data = TRUE; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_report_req_ack | +--------------------------------------------------------------------+ PURPOSE : Processing the signal RL_REPORT_REQ_ACK. */ GLOBAL void rl_report_req_ack (T_rp_user_data *rp_user_data) { GET_INSTANCE_DATA; TRACE_FUNCTION ("rl_report_req_ack()"); if (sms_data) { switch (SMS_INST_GET_STATE (STATE_RL)) { case RL_WAIT_FOR_SEND_ACK: { MCAST (cp_data, U_CP_DATA); /* * stop timer TR2M */ sms_timer_stop(TR2M); rl_build_rp_ack (SMS_RP_REF(sms_data), cp_data, rp_user_data); /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); /* * CP_DATA / RP_ACK ==> */ cp_data_req (cp_data); /* * CP_RELEASE_REQ => */ TRACE_EVENT("CP_RELEASE_REQ_16"); cp_release_req (SMS_INST.ti); break; } default: break; } } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_build_rp_error | +--------------------------------------------------------------------+ PURPOSE : Processing the function RL_BUILD_RP_ERROR. */ GLOBAL void rl_build_rp_error (UBYTE msg_ref, USHORT error, T_U_CP_DATA *cp_data, T_rp_user_data *rp_user_data) { TRACE_FUNCTION ("rl_build_rp_error()"); TRACE_EVENT_P1 ("RP_ERROR.CAUSE sent: 0x%2.2X", (int)error); memset (&cp_data->cp_user_data_ul.rp_error, 0, sizeof (T_rp_error)); cp_data->msg_type = U_CP_DATA; cp_data->cp_user_data_ul.rp_mti = RP_ERROR_UL; cp_data->cp_user_data_ul.reference = msg_ref; cp_data->cp_user_data_ul.v_rp_data_ul = FALSE; cp_data->cp_user_data_ul.v_rp_ack = FALSE; cp_data->cp_user_data_ul.v_rp_error = TRUE; cp_data->cp_user_data_ul.rp_error. rp_cause.v_rp_cause_value = TRUE; if (error < 128) /* GSM 04.11 cause */ { cp_data->cp_user_data_ul.rp_error. rp_cause.rp_cause_value = (UBYTE)error; } else { cp_data->cp_user_data_ul.rp_error. rp_cause.rp_cause_value = SMS_RP_CS_PROTOCOL_ERROR; cp_data->cp_user_data_ul.rp_error. v_rp_user_data = TRUE; } if (rp_user_data NEQ NULL AND rp_user_data->v_tpdu) { memcpy (&cp_data->cp_user_data_ul.rp_error.rp_user_data, rp_user_data, sizeof (T_rp_user_data)); cp_data->cp_user_data_ul.rp_error.v_rp_user_data = TRUE; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_report_req_error | +--------------------------------------------------------------------+ PURPOSE : Processing the signal RL_REPORT_REQ_ERROR. */ GLOBAL void rl_report_req_error (USHORT cause, T_rp_user_data *rp_user_data) { GET_INSTANCE_DATA; TRACE_FUNCTION ("rl_report_req_error()"); if (sms_data) { switch (SMS_INST_GET_STATE (STATE_RL)) { case RL_WAIT_FOR_SEND_ACK: { MCAST (cp_data, U_CP_DATA); /* * stop timer TR2M */ sms_timer_stop(TR2M); rl_build_rp_error (SMS_RP_REF(sms_data), cause, cp_data, rp_user_data); /* * RL state transition RL_IDLE */ SMS_INST_SET_STATE (STATE_RL, RL_IDLE); /* * CP_DATA / RP_ERROR ==> */ cp_data_req (cp_data); break; } default: break; } } } #if defined (GPRS) /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_build_rp_error_gprs | +--------------------------------------------------------------------+ PURPOSE : Processing the function RL_BUILD_RP_ERROR for GSMS. */ GLOBAL void rl_build_rp_error_gprs (UBYTE ti, T_LL_UNITDATA_REQ *data_req, USHORT error, UBYTE msg_ref, T_U_CP_DATA *cp_data, T_stk_cmd *stk_cmd) { TRACE_FUNCTION ("rl_build_rp_error_gprs()"); TRACE_EVENT_P1 ("RP_ERROR.CAUSE sent: 0x%4.2X", (int)error); data_req->sdu.o_buf = ENCODE_OFFSET; cp_data->msg_type = U_CP_DATA; cp_data->cp_user_data_ul.rp_mti = RP_ERROR_UL; cp_data->cp_user_data_ul.reference = msg_ref; cp_data->cp_user_data_ul.v_rp_data_ul = FALSE; cp_data->cp_user_data_ul.v_rp_error = TRUE; memset (&cp_data->cp_user_data_ul.rp_error.rp_cause, 0, sizeof (T_rp_cause)); cp_data->cp_user_data_ul.rp_error. rp_cause.v_rp_cause_value = TRUE; if (error < 128) /* GSM 04.11 cause */ { cp_data->cp_user_data_ul.rp_error. rp_cause.rp_cause_value = (UBYTE)error; cp_data->cp_user_data_ul.rp_error. v_rp_user_data = FALSE; } else { cp_data->cp_user_data_ul.rp_error. rp_cause.rp_cause_value = SMS_RP_CS_PROTOCOL_ERROR; cp_data->cp_user_data_ul.rp_error. v_rp_user_data = TRUE; memset (&cp_data->cp_user_data_ul.rp_error.rp_user_data, 0, sizeof (T_rp_user_data)); if (error >= 256) /* no GSM 03.40 cause */ error = SMS_FCS_UNSPECIFIED; cp_data->cp_user_data_ul.rp_error.rp_user_data. v_tpdu = TRUE; /* cp_data->cp_user_data_ul.rp_error.rp_user_data. sms_deliver_rep_err.tp_fcs = (UBYTE)error; */ } ccd_codeMsg (CCDENT_SMS, UPLINK, (T_MSGBUF *) &data_req->sdu, (UBYTE *) cp_data, NOT_PRESENT_8BIT); /*lint -e415 -e416 Likely creation/access of out-of-bounds pointer */ data_req->sdu.buf[3] = (ti << 4) + PD_SMS; data_req->sdu.o_buf = ENCODE_OFFSET - BSIZE_TI_PD; data_req->sdu.l_buf += BSIZE_TI_PD; if (stk_cmd NEQ NULL) { /* * response from a SIM Toolkit command */ if (stk_cmd->l_cmd NEQ 0) { /* * response TPDU available */ /* change length of rp-error */ data_req->sdu.buf[5] += ((stk_cmd->l_cmd >> 3) + 2); /* add IEI for rp user data */ data_req->sdu.buf[10] = 0x41; /* add length for rp user data */ data_req->sdu.buf [11] = stk_cmd->l_cmd >> 3; /* add TPDU */ memcpy (&data_req->sdu.buf [12], &stk_cmd->cmd[stk_cmd->o_cmd>>3], stk_cmd->l_cmd>>3); /* modify length of CP Data */ data_req->sdu.l_buf += (stk_cmd->l_cmd + 16); } } /*lint +e415 +e416 Likely creation/access of out-of-bounds pointer */ } #endif /* GPRS */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_build_rp_smma | +--------------------------------------------------------------------+ PURPOSE : Processing the function RL_BUILD_RP_SMMA. */ GLOBAL void rl_build_rp_smma (UBYTE msg_ref, T_U_CP_DATA *cp_data) { TRACE_FUNCTION ("rl_build_rp_smma()"); cp_data->cp_user_data_ul.rp_mti = RP_SMMA_UL; cp_data->cp_user_data_ul.reference = msg_ref; cp_data->cp_user_data_ul.v_rp_data_ul = FALSE; cp_data->cp_user_data_ul.v_rp_error = FALSE; cp_data->cp_user_data_ul.v_rp_ack = FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_RL | | STATE : code ROUTINE : rl_temp_failure | +--------------------------------------------------------------------+ PURPOSE : Processing the function RL_TEMP_FAILURE. This is valid for memory available notification attempt. [04.11 Table 8.4 part 3] */ GLOBAL UBYTE rl_temp_failure (UBYTE cause) { TRACE_FUNCTION ("rl_temp_failure()"); switch (cause) { case SMS_RP_CS_UNKNOWN_SUBSCRIBER: case SMS_RP_CS_FAC_NOT_IMPL: case SMS_RP_CS_SEM_INC_MSG: case SMS_RP_CS_INV_MAND_INFO: case SMS_RP_CS_MSG_NON_EXIST: case SMS_RP_CS_MSG_NOT_COMP: case SMS_RP_CS_INFO_NON_EXIST: case SMS_RP_CS_PROTOCOL_ERROR: case SMS_RP_CS_INTERWORKING: return FALSE; /* Non-temporary */ default: return TRUE; /* Temporary */ } } #endif /* #ifndef SMS_RL_C */