FreeCalypso > hg > fc-selenite
view src/g23m-gsm/sms/sms_for.c @ 40:614668bbbc4f
Nucleus: tmt.s ported over from FreeNucleus by XVilka
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 17 Jul 2018 07:55:01 +0000 |
parents | d393cd9bb723 |
children | 85a26478b7de |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : GSM-F&D (8411) | Modul : SMS_FOR +----------------------------------------------------------------------------- | 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 formatter | of the component SMS. +----------------------------------------------------------------------------- */ #ifndef SMS_FOR_C #define SMS_FOR_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 "sms_em.h" /*==== EXPORT ======================================================*/ /*==== PRIVAT ======================================================*/ /*==== VARIABLES ===================================================*/ #if !defined (SHARED_CCD_BUF) GLOBAL UBYTE _decodedMsg [MAX_MSTRUCT_LEN_SMS]; #else GLOBAL UBYTE * _decodedMsg; GLOBAL UBYTE _CCDbuf = FALSE; #endif /*==== FUNCTIONS ===================================================*/ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_FOR | | STATE : code ROUTINE : for_init_sms | +--------------------------------------------------------------------+ PURPOSE : Initialize the formatter (void) */ GLOBAL void for_init_sms (void) { // TRACE_FUNCTION ("for_init_sms()"); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_FOR | | STATE : code ROUTINE : for_get_pd_ti | +--------------------------------------------------------------------+ PURPOSE : Get protocol discriminator and transaction identifier if the incoming message is of sufficient length to contain anythiny useful, this means at least PD, TI and message type. */ LOCAL BOOL for_get_pd_ti (T_sdu *p_sdu, UBYTE *p_pd, UBYTE *p_ti) { if (p_sdu->l_buf >= 16) { *p_pd = p_sdu->buf[p_sdu->o_buf >> 3] & 0x0F; *p_ti = p_sdu->buf[p_sdu->o_buf >> 3] >> 4; *p_ti ^= 0x8; p_sdu->o_buf += BSIZE_TI_PD; p_sdu->l_buf -= BSIZE_TI_PD; return TRUE; } TRACE_EVENT ("message too short"); return FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_FOR | | STATE : code ROUTINE : for_get_new_mt_instance | +--------------------------------------------------------------------+ PURPOSE : This function gets a new MT instance. Basically the same is done here as in GET_NEW_SMS_INSTANCE(), but additionally the special case that the CP-Layer of an old MT transaction waits for the last CP-ACK before the MMSMS_RELEASE_REQ is sent is handled. */ LOCAL T_SMS_DATA * for_get_new_mt_instance (UBYTE ti) { GET_INSTANCE_DATA; TRACE_FUNCTION ("for_get_new_mt_instance()"); /* * Check here whether we are awaiting the last CP-ACK for a MT transaction. * If so, take the new MT message as implicit CP-ACK. */ if (sms_data NEQ NULL) /*lint !e774 (sms_data NEQ NULL) always */ { if (sms_data->data[INST_MT].ti NEQ 0) { /* Old MT instance still exists */ sms_data->inst = INST_MT; switch (SMS_INST_GET_STATE (STATE_CP)) { case CP_WAIT_FOR_ACK: #ifdef GPRS case CP_GSMS_MT_WAIT_FOR_CP_ACK: #endif if (SMS_INST.r_flag) { /* * No further message for the old MT instance expected. Take the * MMSMS_ESTABLISH_IND as implicit CP-ACK for the old instance. */ TRACE_EVENT ("Implicit CP-ACK"); cp_data_ind_cp_ack (); } break; default: break; /* Do nothing */ } } } sms_data = GET_NEW_SMS_INSTANCE(ti); return sms_data; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_FOR | | STATE : code ROUTINE : for_ccd_rp_error_send | +--------------------------------------------------------------------+ PURPOSE : Perform CCD Error check and send rp errors */ LOCAL BOOL for_ccd_rp_error_send (T_D_CP_DATA *cp_data, T_SMS_DATA *sms_data, UBYTE rp_error) { BOOL rp_error_send = FALSE; MCAST (cp_data1, U_CP_DATA); if((SMS_INST_GET_STATE (STATE_CP)) EQ CP_MM_CONNECTION_ESTABLISHED) { rp_error_send = TRUE; rl_build_rp_error (cp_data->cp_user_data_dl.reference, rp_error,cp_data1, NULL); SMS_EM_SEND_RP_ERROR; cp_data_req (cp_data1); cp_send_release_req (SMS_INST.ti); FREE_SMS_INSTANCE (SMS_INST.ti); } return rp_error_send; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_FOR | | STATE : code ROUTINE : for_ccd_error_check | +--------------------------------------------------------------------+ PURPOSE : Perform CCD Error check and returns errors */ LOCAL BOOL for_ccd_error_check (UBYTE *_decodedMsg,T_sdu *buf_sdu, T_SMS_DATA *sms_data,UBYTE ti) { ULONG ccd_err = ERR_NO_MORE_ERROR; T_CCD_ERR_ENTRY *ccd_err_entry; UBYTE p_sdu; UBYTE cp_error_cause = 0; UBYTE length = 0; BOOL cp_error_send = FALSE; BOOL rp_error_send = FALSE; ccd_err_entry = malloc(sizeof(T_CCD_ERR_ENTRY)); if(ccd_err_entry EQ NULL) { TRACE_EVENT("for_ccd_error_check(): MALLOC returned NULL"); return FALSE; } memset(ccd_err_entry,0, sizeof(ccd_err_entry)); /* Message offset value */ p_sdu = (buf_sdu->o_buf/8) - 1; ccd_err = ccd_getFirstFault(&ccd_err_entry); do { /* * Need to set these values everytime we go through fault list of ccd */ cp_error_send = FALSE; rp_error_send = FALSE; /*lint -e415 Likely access of out-of-bounds pointer*/ switch(ccd_err) { case ERR_ELEM_LEN: /* ignore message & send STATUS #96 */ /* * This ccd error will come when there is any error in IE length. * If cp user data length is greater than 249 Octets then this error * is because CP Message IE, so send CP-ERROR * if cp user data length is less than 249, then this ccd error is * because of rp IE length, so RP-ERROR */ switch(_decodedMsg[0]) { case D_CP_DATA: length = buf_sdu->buf[p_sdu+2]; /* * If CP User data length is more than 249 then CCD error is because * of CP Message IE else it will be becasue of RP message IE * Send error accordingly */ if(length < MAX_LEN_CP_USER_DATA) { rp_error_send = for_ccd_rp_error_send((T_D_CP_DATA *)_decodedMsg, sms_data, SMS_RP_CS_INV_MAND_INFO); } if(rp_error_send EQ FALSE) { cp_error_send = TRUE; cp_error_cause = SMS_CP_CS_INV_MAND_INFO; } break; /* * If Message is CP-ACK or CP-ERROR then this ccd error is due to CP * no need to differentiate between RP and CP, These two messages are * intended for CP Layer, So send CP-ERROR */ case B_CP_ACK: case B_CP_ERROR: /* This flag will become FALSE, in case there is CCD warning, so make it * TRUE till we get CCD Error, especially this will happen in default case */ cp_error_send = TRUE; cp_error_cause = SMS_CP_CS_INV_MAND_INFO; break; } break; case ERR_COMPREH_REQUIRED: /* ignore message & send STATUS #96 */ /* * This error will come when Comprehension bit required set is having error in * IE.Comprehension bits can be set inside only CP-DATA message * for RP-ERROR or RP-ACK */ if(_decodedMsg[0] EQ D_CP_DATA) { /* * Comprehension bit error is in RP_ERROR or RP_ACK after RP Cause element */ rp_error_send = for_ccd_rp_error_send((T_D_CP_DATA *)_decodedMsg, sms_data, SMS_RP_CS_INV_MAND_INFO); if(rp_error_send EQ FALSE) { cp_error_send = TRUE; cp_error_cause = SMS_CP_CS_INV_MAND_INFO; } } break; case ERR_MAND_ELEM_MISS: /* ignore message & send STATUS #96 */ /* See bit postions to check whether it is CP or RP Error */ /* * Checking whether this error is in CP message element or RP * message element. This is required to check because both CP and RP * Layer decoding is done inside same CCD function */ /* This is for CP Message decoding error - in Length*/ length = (buf_sdu->l_buf/8); switch(buf_sdu->buf[1]) { case D_CP_DATA: /* Evaluate length of Mandatory CP-DATA/CP-ERROR message */ if(length < MIN_CP_LEN) { cp_error_send = TRUE; cp_error_cause = SMS_CP_CS_INV_MAND_INFO; } else { cp_error_send = FALSE; } break; case B_CP_ERROR:/* This will not have RP DATA, so no need to check for RP */ /* Evaluate length of Mandatory CP-DATA/CP-ERROR message */ if(length < MIN_CP_LEN) { cp_error_send = TRUE; cp_error_cause = SMS_CP_CS_INV_MAND_INFO; } break; case B_CP_ACK:/* This will not have RP DATA, so no need to check for RP */ if(length < MIN_CP_ACK_LEN) { cp_error_send = TRUE; cp_error_cause = SMS_CP_CS_INV_MAND_INFO; } break; default: cp_error_send = TRUE; cp_error_cause = SMS_CP_CS_INV_MAND_INFO; break; } break; case ERR_INVALID_MID: /* ignore message & send STATUS #97 */ /* * Checking whether this error is in CP message element or RP * message element. This is required to check because both CP and RP * Layer decoding is done inside same CCD function */ /* See bit postions to check whether it is CP or RP Error */ /* This is for CP Message decoding error - in Length*/ if ((buf_sdu->buf[1] NEQ D_CP_DATA)||(buf_sdu->buf[1] NEQ B_CP_ACK) ||(buf_sdu->buf[1] NEQ B_CP_ERROR)) { cp_error_send = TRUE; cp_error_cause = SMS_CP_CS_MSG_TYPE_NON_EXIST; } else /* Let RP Layer Handle This ccd error, eventually RP Layer will * send RP-ERROR */ /* This is for RP Message decoding error - in Length*/ cp_error_send = FALSE; break; case ERR_MSG_LEN: /* ignore message & send STATUS #96 */ /* Send CP-ERROR, some problem with Message Length, whole message is garbled */ cp_error_send = TRUE; cp_error_cause = SMS_CP_CS_INV_MAND_INFO; break; case ERR_LEN_MISMATCH: /* ignore message & send STATUS #96 */ /* Send CP-ERROR, some problem with Message Length, whole message is garbled */ cp_error_send = TRUE; cp_error_cause = SMS_CP_CS_INV_MAND_INFO; break; default: TRACE_EVENT_P1 ("Unexpected warnings/errors = %u", ccd_err); /* *Default warnings pass it to RP Layer, decoding at TP will take care of it */ cp_error_send = FALSE; break; } /*lint +e415 Likely access of out-of-bounds pointer*/ ccd_err = ccd_getNextFault(&ccd_err_entry); }while(ccd_err != ERR_NO_MORE_ERROR); if(cp_error_send) { cp_build_cp_error (cp_error_cause); /* * Check if the cmms_mode is enabled or not * If enabled dont release the MM connection */ if(!CMMS_ACTIVE) { cp_send_release_req (ti); SMS_INST_SET_STATE (STATE_CP, CP_IDLE); SMS_INST.r_flag = FALSE; } else { sms_data->cmms_release_pending = TRUE; } rl_error_ind (CAUSE_MAKE(DEFBY_STD, ORIGSIDE_MS, SMSCP_ORIGINATING_ENTITY, cp_error_cause)); FREE_SMS_INSTANCE (ti); } /* These flags return value will decide whether to pass to rp layer further */ return (!rp_error_send && !cp_error_send); } /*---- PRIMITIVES --------------------------------------------------*/ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_FOR | | STATE : code ROUTINE : for_mmsms_establish_ind | +--------------------------------------------------------------------+ PURPOSE : Processing the primitive MMSMS_ESTABLISH_IND */ GLOBAL void for_mmsms_establish_ind (T_MMSMS_ESTABLISH_IND *mmsms_establish_ind) { UBYTE ti; UBYTE pd; CHAR *msg_type; BOOL pass_to_rp = TRUE; /* Enable the PCO to correctly decode the message */ PPASS (mmsms_establish_ind, establish_ind, MMSMS_ESTABLISH_IND); TRACE_FUNCTION ("for_mmsms_establish_ind()"); if (for_get_pd_ti (&establish_ind->sdu, &pd, &ti)) { if ((ti & 0x8) AND (pd EQ PD_SMS)) { register T_SMS_DATA *sms_data = for_get_new_mt_instance (ti); TRACE_EVENT_P1 ("TI %u", ti); if (sms_data) { #if defined (GPRS) SMS_INST.downlink = SMS_DOWNLINK_MMSMS; #endif SMS_INST.cp_ack_pending = FALSE; CCD_START; if(ccd_decodeMsg (CCDENT_SMS, DOWNLINK, (T_MSGBUF *) &establish_ind->sdu, (UBYTE *)_decodedMsg, NOT_PRESENT_8BIT) EQ ccdError) { pass_to_rp = for_ccd_error_check(_decodedMsg,&establish_ind->sdu,sms_data,ti); } if(pass_to_rp) { switch (_decodedMsg[0]) { case D_CP_DATA: cp_est_ind_cp_data ((T_D_CP_DATA *)_decodedMsg); msg_type = "D_CP_DATA"; SMS_EM_RECEIVE_CP_DATA; break; case B_CP_ERROR: { MCAST (error, B_CP_ERROR); cp_est_ind_cp_error (error->cp_cause); msg_type = "B_CP_ERROR"; SMS_EM_RECEIVE_CP_ERROR; break; } case B_CP_ACK: cp_est_ind_cp_ack (); msg_type = "B_CP_ACK"; SMS_EM_RECEIVE_CP_ACKNOWLEDGE; break; default: cp_est_ind_cp_unknown (); msg_type = "UNKNOWN_MESSAGE"; SMS_EM_RECEIVE_UNKNOWN; break; } TRACE_BINDUMP(sms_handle, TC_USER4, msg_type, (&(establish_ind->sdu.buf[0]) + ((establish_ind->sdu.o_buf >> 3) -1)), ((establish_ind->sdu.l_buf >> 3) + 1)); } CCD_END; } else { /* * no further instance available */ CCD_START; ccd_decodeMsg (CCDENT_SMS, DOWNLINK, (T_MSGBUF *) &establish_ind->sdu, (UBYTE *) _decodedMsg, NOT_PRESENT_8BIT); switch (_decodedMsg[0]) { case D_CP_DATA: { MCAST (d_cp_data, D_CP_DATA); MCAST (cp_data, U_CP_DATA); /* * U_CP_DATA contains a maximum of 252 Bytes */ PALLOC_SDU (data_req, MMSMS_DATA_REQ, LEN_U_CP_DATA); data_req->sdu.o_buf = ENCODE_OFFSET; rl_build_rp_error (d_cp_data->cp_user_data_dl.reference, SMS_RP_CS_PROTOCOL_ERROR, cp_data, NULL); cp_data->msg_type = U_CP_DATA; ccd_codeMsg (CCDENT_SMS, UPLINK, (T_MSGBUF *)&data_req->sdu, (UBYTE *)cp_data, NOT_PRESENT_8BIT); cp_add_pd_ti (ti, &data_req->sdu); TRACE_BINDUMP(sms_handle, TC_USER4, "U_CP_DATA", (&(data_req->sdu.buf[0]) + ((data_req->sdu.o_buf >> 3) -1)), ((data_req->sdu.l_buf >> 3) + 1)); PSENDX (MM, data_req); break; } default: TRACE_EVENT_P1 ("Unexpected Message = %u", _decodedMsg[0]); break; } CCD_END; { PALLOC (release_req, MMSMS_RELEASE_REQ); release_req->ti = ti; PSENDX (MM, release_req); } SMS_EM_UNKNOWN_TRANSACTION; } } else { TRACE_EVENT_P2 ("TI or PD wrong, PD=%d, TI=%d", pd, ti); } } PFREE (establish_ind); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_FOR | | STATE : code ROUTINE : for_mmsms_data_ind | +--------------------------------------------------------------------+ PURPOSE : Processing the primitive MMSMS_DATA_IND */ GLOBAL void for_mmsms_data_ind (T_MMSMS_DATA_IND *mmsms_data_ind) { UBYTE ti; UBYTE pd; CHAR *msg_type; BOOL pass_to_rp = TRUE; /* Enable the PCO to correctly decode the message */ PPASS (mmsms_data_ind, data_ind, MMSMS_DATA_IND); if (for_get_pd_ti (&data_ind->sdu, &pd, &ti)) { TRACE_FUNCTION_P1 ("for_mmsms_data_ind(TI=%u)", ti); if (/*((! ti) OR (ti >= 8)) AND*/ (pd EQ PD_SMS)) { register T_SMS_DATA *sms_data = GET_SMS_INSTANCE(ti); if (sms_data) { CCD_START; if(ccd_decodeMsg (CCDENT_SMS, DOWNLINK, (T_MSGBUF *) &data_ind->sdu, (UBYTE *)_decodedMsg, NOT_PRESENT_8BIT) EQ ccdError) { pass_to_rp = for_ccd_error_check(_decodedMsg,&data_ind->sdu,sms_data,ti); } if(pass_to_rp) { switch (_decodedMsg[0]) { case D_CP_DATA: cp_data_ind_cp_data ((T_D_CP_DATA *)_decodedMsg); msg_type = "D_CP_DATA"; break ; case B_CP_ERROR: { MCAST (error, B_CP_ERROR); cp_data_ind_cp_error (error->cp_cause); msg_type = "B_CP_ERROR"; break ; } case B_CP_ACK: cp_data_ind_cp_ack (); msg_type = "B_CP_ACK"; break ; default: cp_data_ind_cp_unknown (); msg_type = "UNKNOWN MESSAGE"; break ; } TRACE_BINDUMP(sms_handle, TC_USER4, msg_type, (&(data_ind->sdu.buf[0]) + ((data_ind->sdu.o_buf >> 3) -1)), ((data_ind->sdu.l_buf >> 3) + 1)); } CCD_END; } } else { TRACE_EVENT_P1 ("PD wrong, PD=%d", pd); } } else { TRACE_ERROR("for_mmsms_data_ind() error evaluating PD TI"); } PFREE (data_ind) ; } #if defined (GPRS) /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_CP | | STATE : code ROUTINE : cp_ll_unitdata_ind | +--------------------------------------------------------------------+ PURPOSE : Processing the signal LL_UNITDATA_IND (GSMS only). */ GLOBAL void for_ll_unitdata_ind (T_LL_UNITDATA_IND *ll_unitdata_ind) { UBYTE ti; UBYTE pd; CHAR *msg_type; T_SMS_DATA *sms_global = GET_INSTANCE(0); /* Enable the PCO to correctly decode the message */ PPASS (ll_unitdata_ind, unitdata_ind, LL_UNITDATA_IND); TRACE_FUNCTION ("for_ll_unitdata_ind()"); if (!(unitdata_ind->sapi EQ LL_SAPI_7)) { TRACE_EVENT ("SAPI not LL_SAPI_7"); PFREE (unitdata_ind); return; } if (sms_global) /*lint !e774 (sms_global) always */ { if (SMS_SMS_FLOW(sms_global) NEQ SMS_FLOW_AVAILABLE) { TRACE_ERROR ("unexpected primitive"); } /* * data has been received, mark flow status as busy */ SMS_SMS_FLOW(sms_global) = SMS_FLOW_BUSY; } if (for_get_pd_ti (&unitdata_ind->sdu, &pd, &ti)) { if (/*((! ti) OR (ti >= 8)) AND*/ (pd EQ PD_SMS)) { register T_SMS_DATA *sms_data = GET_SMS_INSTANCE(ti); if (sms_data) { CCD_START; ccd_decodeMsg (CCDENT_SMS, DOWNLINK, (T_MSGBUF *) &unitdata_ind->sdu, (UBYTE *) _decodedMsg, NOT_PRESENT_8BIT); switch (_decodedMsg[0]) { case D_CP_DATA: cp_data_ind_cp_data ((T_D_CP_DATA *)_decodedMsg); msg_type = "D_CP_DATA"; break ; case B_CP_ERROR: { MCAST (error, B_CP_ERROR); cp_data_ind_cp_error (error->cp_cause); msg_type = "B_CP_ERROR"; break ; } case B_CP_ACK: cp_data_ind_cp_ack (); msg_type = "B_CP_ACK"; break ; default: cp_data_ind_cp_unknown (); msg_type = "UNKNOWN MESSAGE"; break ; } CCD_END; TRACE_BINDUMP(sms_handle, TC_USER4, msg_type, (&(unitdata_ind->sdu.buf[0]) + ((unitdata_ind->sdu.o_buf >> 3) -1)), ((unitdata_ind->sdu.l_buf >> 3) + 1)); } else { /* * no SMS instance associated with pid, try to create new one */ if (ti & 0x8) { register T_SMS_DATA *sms_data = for_get_new_mt_instance (ti); if (sms_data) { CCD_START; ccd_decodeMsg (CCDENT_SMS, DOWNLINK, (T_MSGBUF *) &unitdata_ind->sdu, (UBYTE *) _decodedMsg, NOT_PRESENT_8BIT); SMS_INST_SET_STATE (STATE_CP, CP_GSMS_IDLE); SMS_INST.downlink = SMS_DOWNLINK_LL; switch (_decodedMsg[0]) { case D_CP_DATA: cp_data_ind_cp_data ((T_D_CP_DATA*) _decodedMsg); msg_type = "D_CP_DATA"; break ; case B_CP_ERROR: { MCAST (error, B_CP_ERROR); cp_data_ind_cp_error (error->cp_cause); msg_type = "B_CP_ERROR"; } break ; case B_CP_ACK: cp_data_ind_cp_ack (); msg_type = "B_CP_ACK"; break ; default: cp_data_ind_cp_unknown (); msg_type = "UNKNOWN MESSAGE"; break ; } CCD_END; TRACE_BINDUMP(sms_handle, TC_USER4, msg_type, (&(unitdata_ind->sdu.buf[0]) + ((unitdata_ind->sdu.o_buf >> 3) -1)), ((unitdata_ind->sdu.l_buf >> 3) + 1)); } else { /* * no further instance available, send rp error message */ register T_SMS_DATA* sms_data_main = GET_INSTANCE(0); CCD_START; ccd_decodeMsg (CCDENT_SMS, DOWNLINK, (T_MSGBUF *) &unitdata_ind->sdu, (UBYTE *) _decodedMsg, NOT_PRESENT_8BIT); if (sms_data_main) /*lint !e774 (sms_data_main) always */ { if ((_decodedMsg[0] EQ D_CP_DATA) && (sms_data_main->llc_flow EQ SMS_LLC_AVAILABLE)) { UBYTE msg_ref; MCAST (d_cp_data, D_CP_DATA); MCAST (cp_data, U_CP_DATA); /* * U_CP_DATA contains a maximum of 252 Bytes */ PALLOC_SDU (unitdata_req, LL_UNITDATA_REQ, LEN_U_CP_DATA); cp_init_ll_unitdata_req (unitdata_req); msg_ref = d_cp_data->cp_user_data_dl.reference; rl_build_rp_error_gprs (ti, unitdata_req, SMS_RP_CS_PROTOCOL_ERROR, msg_ref, cp_data, NULL); sms_data_main->llc_flow = SMS_LLC_BUSY; TRACE_BINDUMP(sms_handle, TC_USER4, "U_CP_DATA", (&(unitdata_req->sdu.buf[0]) + ((unitdata_req->sdu.o_buf >> 3) -1)), ((unitdata_req->sdu.l_buf >> 3) + 1)); PSENDX (LLC, unitdata_req); } } CCD_END; } } else { TRACE_EVENT_P1 ("Unknown TI with response flag set, TI=%d", ti); } } } else { TRACE_EVENT_P1 ("PD wrong, PD=%d", pd); } } PFREE (unitdata_ind); /* * Receive ready, if sending is not blocked */ // if (SMS_LLC_FLOW(sms_global) NEQ SMS_LLC_BUSY_WAITING) { cp_send_getunitdata_req (); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8410) MODULE : SMS_CP | | STATE : code ROUTINE : for_ll_unitready_ind | +--------------------------------------------------------------------+ PURPOSE : Processing the signal LL_UNITREADY_IND (GSMS only). */ GLOBAL void for_ll_unitready_ind (T_LL_UNITREADY_IND *unitready_ind) { GET_INSTANCE_DATA; TRACE_FUNCTION ("ll_unitready_ind()"); if ((unitready_ind->sapi NEQ LL_SAPI_7) || !sms_data) /*lint !e774 (!sms_data) never */ { TRACE_EVENT ("ll_unitready_ind(): SAPI not LL_SAPI_7 or no SMS instance"); PFREE (unitready_ind); return; } if (SMS_LLC_FLOW(sms_data) EQ SMS_LLC_BUSY_WAITING) { /* * find the message waiting for LLC */ GET_MO_INSTANCE(sms_data); if (SMS_INST_GET_STATE (STATE_CP) EQ CP_GSMS_IDLE) { switch (SMS_CP_ACK_TYPE(sms_data)) { case SMS_CP_ACK: cp_build_cp_ack (); SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY; if (SMS_CP_UDL(sms_data) NEQ NULL) { rl_data_ind (SMS_CP_UDL(sms_data)); MFREE(SMS_CP_UDL(sms_data)); SMS_CP_UDL(sms_data) = NULL; } if (SMS_INST.r_flag) { /* * terminate SMS instance */ SMS_INST_SET_STATE (STATE_CP, CP_IDLE); SMS_INST.r_flag = FALSE; FREE_SMS_INSTANCE (SMS_INST.ti); } break; case SMS_CP_ERROR: cp_build_cp_error (SMS_CP_CAUSE(sms_data)); SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY; /* * terminate SMS instance */ SMS_INST_SET_STATE (STATE_CP, CP_IDLE); SMS_INST.r_flag = FALSE; FREE_SMS_INSTANCE (SMS_INST.ti); break; default: SMS_LLC_FLOW(sms_data) = SMS_LLC_AVAILABLE; break; } SMS_CP_ACK_TYPE(sms_data) = SMS_CP_NONE; } else { SMS_LLC_FLOW(sms_data) = SMS_LLC_AVAILABLE; } if (SMS_LLC_FLOW(sms_data) EQ SMS_LLC_AVAILABLE) { GET_MT_INSTANCE(sms_data); switch (SMS_INST_GET_STATE (STATE_CP)) { case CP_GSMS_IDLE: case CP_GSMS_MT_WAIT_FOR_RP_ACK: case CP_GSMS_MT_WAIT_FOR_CP_ACK: switch (SMS_CP_ACK_TYPE(sms_data)) { case SMS_CP_ACK: cp_build_cp_ack (); if (SMS_INST_GET_STATE (STATE_CP) EQ CP_GSMS_MT_WAIT_FOR_CP_ACK) { /* stored CP-DATA will follow */ SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY_WAITING; } else { SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY; } break; case SMS_CP_ERROR: cp_build_cp_error (SMS_CP_CAUSE(sms_data)); SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY; /* * terminate SMS instance */ SMS_INST_SET_STATE (STATE_CP, CP_IDLE); SMS_INST.r_flag = FALSE; FREE_SMS_INSTANCE (SMS_INST.ti); break; default: if (SMS_INST_GET_STATE (STATE_CP) EQ CP_GSMS_MT_WAIT_FOR_CP_ACK AND SMS_DATA_REQ(sms_data) NEQ 0) { cp_send_data_gsms (); SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY; } break; } SMS_CP_ACK_TYPE(sms_data) = SMS_CP_NONE; break; default: break; } } if (SMS_LLC_FLOW(sms_data) EQ SMS_LLC_AVAILABLE) { GET_MO_INSTANCE(sms_data); switch (SMS_INST_GET_STATE (STATE_CP)) { case CP_GSMS_MO_WAIT_FOR_CP_ACK: cp_send_data_gsms (); SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY; break; case CP_GSMS_IDLE: cp_send_data_gsms (); rl_proceed (); SMS_INST.r_flag = TRUE; SMS_INST_SET_STATE (STATE_CP, CP_GSMS_MO_WAIT_FOR_CP_ACK); SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY; break; default: break; } } } else { SMS_LLC_FLOW(sms_data) = SMS_LLC_AVAILABLE; } PFREE (unitready_ind); // cp_send_getunitdata_req (sms_data); } #endif /* GPRS */ #endif /* #ifndef SMS_FOR_C */