FreeCalypso > hg > fc-tourmaline
diff src/g23m-gprs/sndcp/sndcp_mgp.c @ 1:fa8dc04885d8
src/g23m-*: import from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:25:50 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-gprs/sndcp/sndcp_mgp.c Fri Oct 16 06:25:50 2020 +0000 @@ -0,0 +1,3192 @@ +/* ++----------------------------------------------------------------------------- +| Project : GPRS (8441) +| Modul : sndcp_mgp.c ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : This modul is part of the entity SNDCP and implements all +| functions to handles the incoming primitives as described in +| the SDL-documentation (MG-statemachine) ++----------------------------------------------------------------------------- +*/ + + + +#define ENTITY_SNDCP + +/*==== INCLUDES =============================================================*/ + +#include "typedefs.h" /* to get Condat data types */ +#include "vsi.h" /* to get a lot of macros */ +#include "macdef.h" +#include "gsm.h" /* to get a lot of macros */ +#include "prim.h" /* to get the definitions of used SAP and directions */ +#include "dti.h" +#ifdef _SNDCP_DTI_2_ +#include <string.h> +#endif /* _SNDCP_DTI_2_ */ + +#include "sndcp.h" /* to get the global entity definitions */ +#include "sndcp_f.h" /* to get the functions to access the global arrays*/ +#include "sndcp_mgf.h" /* to get the local functions of service mg */ +#include "sndcp_nuf.h" +#include "sndcp_nus.h" /* to get the internal signals toservice nu */ +#include "sndcp_nds.h" /* to get the internal signals to service nd */ +#include "sndcp_cias.h" /* to get the internal signals to service cia */ +#include "sndcp_sds.h" /* to get the signals to sd service */ +#include "sndcp_sus.h" /* to get the internal signals to service su */ +#include "sndcp_suas.h" /* to get the internal signals to service sua */ +#include "sndcp_sdas.h" /* to get the signals to sda service */ +#include "sndcp_sdf.h" +#include "sndcp_sdaf.h" + +/*==== CONST ================================================================*/ +#define TCPIP_NAME "TCP" +/*==== LOCAL VARS ===========================================================*/ + +/*==== PRIVATE FUNCTIONS ====================================================*/ + + +/* ++------------------------------------------------------------------------------ +| Function : mg_est_cnf_est_pending ++------------------------------------------------------------------------------ +| Description : After receiving an ll_establish_cnf, an snsm_activate_res +| is sent to each waiting nsapi, sua and sda, sd are notified. +| +| Parameters : ll_establish_cnf +| ++------------------------------------------------------------------------------ +*/ +LOCAL void mg_est_cnf_est_pending (T_LL_ESTABLISH_CNF* ll_establish_cnf) { + UBYTE nsapi = 0; + USHORT sapi_state = MG_IDLE; + + TRACE_FUNCTION( "mg_est_cnf_est_pending" ); + + /* + * If MG_REL_NEC_LOC/PEER is set for the affected sapi, there will be no + * nsapi waiting for LL_ESTABLISH_CNF. + * LL_RELEASE_REQ must be sent. + */ + sndcp_get_sapi_state(ll_establish_cnf->sapi, &sapi_state); + if ((sapi_state & MG_REL_NEC_LOC) > 0) { + PALLOC(ll_release_req, LL_RELEASE_REQ); + + ll_release_req->sapi = ll_establish_cnf->sapi; + ll_release_req->local = TRUE; + sndcp_unset_sapi_state(ll_release_req->sapi, MG_REL_NEC_LOC); + /* + * Set the "state" for the affected and sapi to MG_REL. + */ + sndcp_set_sapi_state(ll_establish_cnf->sapi, MG_REL); + sndcp_unset_sapi_state(ll_establish_cnf->sapi, MG_EST); + + PSEND(hCommLLC, ll_release_req); + return; + + } + + if ((sapi_state & MG_REL_NEC_PEER) > 0) { + PALLOC(ll_release_req, LL_RELEASE_REQ); + + ll_release_req->sapi = ll_establish_cnf->sapi; + ll_release_req->local = FALSE; + sndcp_unset_sapi_state(ll_release_req->sapi, MG_REL_NEC_PEER); + /* + * Set the "state" for the affected and sapi to MG_REL. + */ + sndcp_set_sapi_state(ll_establish_cnf->sapi, MG_REL); + sndcp_unset_sapi_state(ll_establish_cnf->sapi, MG_EST); + + PSEND(hCommLLC, ll_release_req); + + return; + } + if ((sapi_state & MG_XID_NEC) > 0) { + sndcp_unset_sapi_state(ll_establish_cnf->sapi, MG_EST); + return; + } + + + /* + * Send an SNSM_ACTIVATE_RES to all nsapis that are waiting for + * an LL_ESTABLISH_CNF. + */ + for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) { + + USHORT nsapi_state = MG_IDLE; + USHORT local_sapi_state = MG_IDLE; + UBYTE sapi = 0; + UBYTE sapi_index = 0; + + sndcp_get_nsapi_state(nsapi, &nsapi_state); + sndcp_get_nsapi_sapi(nsapi, &sapi); + sndcp_get_sapi_state(sapi, &local_sapi_state); + sndcp_get_sapi_index(sapi, &sapi_index); + if ((nsapi_state & MG_ACT) > 0 && + (local_sapi_state & MG_XID) == 0 && + sapi == ll_establish_cnf->sapi) { + + +#ifndef SNDCP_UPM_INCLUDED + mg_dti_open(nsapi); +#else + nu_ready_ind_if_nec(nsapi); +#endif + + mg_send_snsm_activate_res(nsapi); + + sndcp_unset_nsapi_state(nsapi, MG_ACT); + + } + if ((nsapi_state & MG_ACT) > 0 && + (local_sapi_state & MG_XID) > 0 && + sapi == ll_establish_cnf->sapi) { + + /* + * Open DTI connection. + */ +#ifndef SNDCP_UPM_INCLUDED + mg_dti_open(nsapi); +#else + nu_ready_ind_if_nec(nsapi); +#endif + + mg_send_snsm_activate_res(nsapi); + + /* + * Set nsapi state to MG_IDLE. + */ + sndcp_unset_nsapi_state(nsapi, MG_ACT); + + } + if (((local_sapi_state & MG_EST) > 0) && + ((nsapi_state & MG_ACT) == 0) && + ((local_sapi_state & MG_XID) > 0)) { + sig_mg_nu_reset_ack(nsapi, 0, 0, FALSE); + } + + + } /* for (nsapi... */ + + /* + * All nsapis at this sapi that use ack mode, enter recovery state. + */ + for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) { + UBYTE sapi = 0; + BOOL ack = FALSE; + + sndcp_get_nsapi_sapi(nsapi, &sapi); + sndcp_get_nsapi_ack(nsapi, &ack); + if (ack && sapi == ll_establish_cnf->sapi) { + sig_mg_cia_delete_npdus(nsapi); + sig_mg_sua_delete_pdus(nsapi, sapi, FALSE); + sig_mg_nu_recover(nsapi); + sig_mg_nd_recover(nsapi); + } + } /* for all nsapis */ + + + sndcp_unset_sapi_state(ll_establish_cnf->sapi, MG_XID); + sndcp_unset_sapi_state(ll_establish_cnf->sapi, MG_EST); + + sndcp_set_sapi_ack(ll_establish_cnf->sapi, TRUE); + /* + * Service sda may now leave state SDA_ESTABLISH_REQUESTED. + */ + sig_mg_sda_end_est(ll_establish_cnf->sapi, TRUE); + /* + * Services su and sua may now leave suspend state. + */ + sig_mg_su_resume(ll_establish_cnf->sapi); + sig_mg_sua_resume(ll_establish_cnf->sapi); + mg_resume_affected_nus(ll_establish_cnf->sapi); + + /* + * If req xid has been changed during establishment, resend it. + */ + mg_resend_xid_if_nec(ll_establish_cnf->sapi); + + +} /* mg_est_cnf_est_pending() */ + +/* ++------------------------------------------------------------------------------ +| Function : mg_check_unset_nsapi_flow_ctrl_flag ++------------------------------------------------------------------------------ +| Description : This function checks if flow control is received before PDP +| activation for the nsapi by checking the bit in nsapi_rcv_rdy_b4_used flag +| for the NSAPI +| Depending on the mode calls the corresponding function to set the +| nsapi recv flag to true. +| In all cases unset the NSAPI bit in the nsapi_rcv_rdy_b4_used flag +| +| Parameters : affected nsapi, mode +| ++------------------------------------------------------------------------------ +*/ +LOCAL void mg_check_unset_nsapi_flow_ctrl_flag (UBYTE nsapi, UBYTE mode) { + + /* check if flow control is received before PDP activation */ + if ((sndcp_data->nsapi_rcv_rdy_b4_used & (0x001 << nsapi)) > 0) + { + if (mode == SNDCP_ACK) + sda_set_nsapi_rec(nsapi, TRUE); + else if (mode == SNDCP_UNACK) + sd_set_nsapi_rec(nsapi, TRUE); + + /* Set flow control flag for the NSAPI to FALSE */ + sndcp_data->nsapi_rcv_rdy_b4_used &= ~(0x001 << nsapi); + } +} + +/* ++------------------------------------------------------------------------------ +| Function : mg_get_downlink_data ++------------------------------------------------------------------------------ +| Description : If at the given sapi an nsapi is active and using +| unacknowledged LLC operation mode then sig_mg_sd_getunitdata +| (sapi) is sent. +| If at the given sapi an nsapi is active and using +| acknowledged LLC operation mode then sig_mg_sda_getdata(sapi) +| is sent. +| +| Parameters : affected sapi +| ++------------------------------------------------------------------------------ +*/ +LOCAL void mg_get_downlink_data (UBYTE sapi) { + + /* + * Are unack or ack nsapis used? + */ + UBYTE nsapi; + + TRACE_FUNCTION( "mg_get_downlink_data" ); + + for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) { + BOOL used = FALSE; + + sndcp_is_nsapi_used(nsapi, &used); + if (used) { + UBYTE local_sapi = 0; + + sndcp_get_nsapi_sapi(nsapi, &local_sapi); + if (sapi == local_sapi) { + BOOL ack = FALSE; + USHORT nsapi_state = MG_IDLE; + USHORT sapi_state = MG_IDLE; + + sndcp_get_nsapi_state(nsapi, &nsapi_state); + sndcp_get_sapi_state(local_sapi, &sapi_state); + if (((sapi_state & MG_XID) == 0) && + ((sapi_state & MG_EST) == 0)) { + sndcp_get_nsapi_ack(nsapi, &ack); + if(ack){ + sig_mg_sda_getdata(sapi, nsapi); + } else { + sig_mg_sd_getunitdata(sapi, nsapi); + } + } + } + } + } /* for all nsapis */ + +} /* mg_get_downlink_data() */ + + + + +/* ++------------------------------------------------------------------------------ +| Function : mg_is_comp_available ++------------------------------------------------------------------------------ +| Description : is another compressor available +| +| Parameters : sapi, ack, kind, available +| +| Note: implementation dependent!!! +| ++------------------------------------------------------------------------------ +*/ +LOCAL void mg_is_comp_available (UBYTE sapi, + BOOL ack, + UBYTE kind, + UBYTE msid, + BOOL* available) { + + UBYTE nsapi = 0; + USHORT nsapi_set = 0; + UBYTE sapi_index = 0; + BOOL local_ack = FALSE; + T_XID_BLOCK comp_xid_block; + U16 sapi_state = MG_IDLE; + + TRACE_FUNCTION( "mg_is_comp_available" ); + + sndcp_get_sapi_index(sapi, &sapi_index); + + /* + * Implementation dependent! + * Currently only implemented for VJ. + * Is requested xid block for the given SAPI holding a compressor of the + * given kind? + */ + if (sndcp_data->vj_count < SNDCP_MAX_VJ_COUNT) { + *available = TRUE; + return; + } + + /* + * If an XID negotiation is ongoing we have to look at the compressors in + * req_xid_block: is a compressor requested that will be used for the same + * LLC operation mode? + * If no negotiation is pending, we must look at the cur_xid_block of the + * SAPI. + * Note: since we have checked before that vj_count has already reached + * SNDCP_MAX_VJ_COUNT, ther must be an appropriate compressor on the + * used SAPI, current or requested which may also be used for this nsapi. + * No new compressor is available. + */ + + sndcp_get_sapi_state(sapi, &sapi_state); + + if (((sapi_state & MG_EST) == 0) && + ((sapi_state & MG_XID) == 0)) { + + comp_xid_block = sndcp_data->mg.cur_xid_block[sapi_index]; + } else { + comp_xid_block = sndcp_data->mg.req_xid_block[sapi_index]; + } + + + nsapi_set = comp_xid_block.vj.nsapis; + + if (! comp_xid_block.vj.is_set || + (comp_xid_block.vj.is_set && nsapi_set == 0)) { + *available = FALSE; + return; + } + + + /* + * If the LLC operation mode of the cur_xid_block is not equal to the + * given LLC operation mode, no compressor is available. + */ + for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) { + if (((1 << nsapi) & nsapi_set) > 0) { + break; + } + } + if(nsapi < SNDCP_NUMBER_OF_NSAPIS){ + sndcp_get_nsapi_ack(nsapi, &local_ack); + if ((local_ack && ack) || + (! local_ack && ack)) { + *available = TRUE; + return; + } + } else { + /* + * No nsapi yet using the compressor. + */ + *available = TRUE; + return; + } + *available = FALSE; + return; + +} /* mg_is_comp_available() */ + +/* ++------------------------------------------------------------------------------ +| Function : mg_ll_release_to_snsm_status ++------------------------------------------------------------------------------ +| Description : Converts ll_release_ind->cause to snsm_status_req->cause +| +| Parameters : ll_release_ind->error_cause +| Return : snsm_status_req->cause +| ++------------------------------------------------------------------------------ +*/ +LOCAL U16 mg_ll_release_to_snsm_status (U16 ll_cause) { + + + switch (ll_cause) + { +#ifdef SNDCP_2to1 + return ll_cause; +#else /*SNDCP_2to1*/ +#ifdef SNDCP_UPM_INCLUDED + /* Here the cause values from LL sap is converted to + * cause values from CAUSE include SAP. This is because + * SM expects these cause values. + */ + case LL_RELCS_INVALID_XID: + return CAUSE_LLC_INVALID_XID; + case LL_RELCS_DM_RECEIVED: + return CAUSE_LLC_DM_RECEIVED; + case LL_RELCS_NO_PEER_RES: + return CAUSE_LLC_NO_PEER_RES; + case LL_RELCS_NORMAL: + return CAUSE_LLC_NORMAL_REL; +#endif /* SNDCP_UPM_INCLUDED */ +#endif /*SNDCP_2to1*/ + default: + return ll_cause; + } + +} /* mg_ll_release_to_snsm_status() */ + +/* ++------------------------------------------------------------------------------ +| Function : mg_ll_status_to_snsm_status ++------------------------------------------------------------------------------ +| Description : Converts ll_status_ind->error_cause to snsm_status_req->cause +| +| Parameters : ll_status_ind->error_cause +| Return : snsm_status_req->cause +| ++------------------------------------------------------------------------------ +*/ +LOCAL U16 mg_ll_status_to_snsm_status (U16 ll_error_cause) { + + switch (ll_error_cause) + { +#ifdef SNDCP_2to1 + return ll_error_cause; +#else /*SNDCP_2to1*/ +#ifdef SNDCP_UPM_INCLUDED + /* Here the cause values from LL sap is converted to + * cause values from CAUSE include SAP. This is because + * SM expects these cause values. + */ + case LL_ERRCS_INVALID_XID: + return CAUSE_LLC_INVALID_XID; + case LL_ERRCS_NO_PEER_RES: + return CAUSE_LLC_NO_PEER_RES; +#endif /* SNDCP_UPM_INCLUDED */ +#endif /* SNDCP_2to1 */ + default: + return ll_error_cause; + + + } +} /* mg_ll_status_to_snsm_status() */ + +/* ++------------------------------------------------------------------------------ +| Function : mg_mod_ack_unack ++------------------------------------------------------------------------------ +| Description : An snsm_modify_ind has indicated that the operation mode of +| the affected nsapi changed from acknowledged to unacknowledged. +| +| Parameters : snsm_modify_ind +| ++------------------------------------------------------------------------------ +*/ +#ifdef SNDCP_UPM_INCLUDED +LOCAL void mg_mod_ack_unack (T_SN_MODIFY_REQ* snsm_modify_ind) { +#else +LOCAL void mg_mod_ack_unack (T_SNSM_MODIFY_IND* snsm_modify_ind) { +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + UBYTE nsapi = 0; + BOOL alone = TRUE; + + TRACE_FUNCTION( "mg_mod_ack_unack" ); + + mg_delete_npdus(snsm_modify_ind->nsapi); + sig_mg_nu_reset(snsm_modify_ind->nsapi, TRUE); + /* + * LL_RELEASE_IND expected, if this was the only ack nsapi on the affected + * sapi. + */ + while (nsapi < SNDCP_NUMBER_OF_NSAPIS && alone) { + + UBYTE sapi = 0; + BOOL ack = FALSE; + + sndcp_get_nsapi_sapi(nsapi, &sapi); + sndcp_get_nsapi_ack(nsapi, &ack); + alone = ! (nsapi != snsm_modify_ind->nsapi && + sapi == snsm_modify_ind->sapi && + ack); + + sndcp_set_nsapi_ack(snsm_modify_ind->nsapi, FALSE); + nsapi++; + } + if (alone) { + sndcp_data->mg.mod_expects |= MG_MOD_X_REL; + } + +} /* mg_mod_ack_unack() */ + +/* ++------------------------------------------------------------------------------ +| Function : mg_mod_nsapi_new ++------------------------------------------------------------------------------ +| Description : An snsm_modify_ind has indicated the creation of a new NSAPI. +| Actions similar to snsm_activate_ind are taken, but the +| establishment is never initiated by the MS. Everything +| concerning the given nsapi is set to acknowlegded, but the +| LLC establishment is expected to be done by the net. +| +| Parameters : snsm_modify_ind +| ++------------------------------------------------------------------------------ +*/ +#ifdef SNDCP_UPM_INCLUDED +LOCAL void mg_mod_nsapi_new (T_SN_MODIFY_REQ* snsm_modify_ind) { +#else +LOCAL void mg_mod_nsapi_new (T_SNSM_MODIFY_IND* snsm_modify_ind) { +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + /* + * LLC mode specified? + */ + BOOL spec = FALSE; + /* + * LLC mode acknowledged? + */ + BOOL b = FALSE; + + TRACE_FUNCTION( "mg_mod_nsapi_new" ); + + sndcp_set_nsapi_used(snsm_modify_ind->nsapi, TRUE); + sndcp_set_nsapi_qos(snsm_modify_ind->nsapi, + snsm_modify_ind->snsm_qos); + sndcp_set_nsapi_sapi(snsm_modify_ind->nsapi, + snsm_modify_ind->sapi); + sndcp_set_nsapi_prio(snsm_modify_ind->nsapi, + snsm_modify_ind->radio_prio); +#ifdef REL99 + sndcp_set_nsapi_pktflowid(snsm_modify_ind->nsapi, + snsm_modify_ind->pkt_flow_id); +#endif /*REL99*/ + + mg_is_ack(snsm_modify_ind->snsm_qos, &spec, &b); + if (spec) { + if (b) { + + BOOL ack = FALSE; + + /* + * The NSAPI will use acknowledged LLC operation mode. + */ + sndcp_set_nsapi_ack(snsm_modify_ind->nsapi, TRUE); + /* + * Is the affected SAPI already in ack mode? + */ + sndcp_get_sapi_ack(snsm_modify_ind->sapi, &ack); + /* + * Reset service nu to acknowledged LLC mode. + */ +#ifdef SNDCP_UPM_INCLUDED + sig_mg_nu_reset_ack(snsm_modify_ind->nsapi, + 0, /*snsm_modify_ind->send_no, FIXME !!*/ + 0, /*snsm_modify_ind->rec_no, FIXME !!*/ + TRUE); +#else + sig_mg_nu_reset_ack(snsm_modify_ind->nsapi, + snsm_modify_ind->send_no, + snsm_modify_ind->rec_no, + TRUE); +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + } + } + /* + * LL_ESTABLISH_IND expected. + */ + sndcp_data->mg.mod_expects |= MG_MOD_X_EST; + +} /* mg_mod_nsapi_new() */ + +/* ++------------------------------------------------------------------------------ +| Function : mg_mod_res_if_nec ++------------------------------------------------------------------------------ +| Description : The service var 'mod_expects' informs about the measures to be +| taken before an SNSM_MODIFY_RES is sent. +| If it is set to MG_MOD_X_READY then one SNSM_MODIFY_RES will be sent to each +| of the nsapis indicated in service var 'waiting_nsapis'. +| Sets 'waiting_nsapis' to 0. +| Sets 'mod_expects' to MG_MOD_X_NONE. +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +LOCAL void mg_mod_res_if_nec (void) { + + TRACE_FUNCTION( "mg_mod_res_if_nec" ); + + if (sndcp_data->mg.mod_expects == MG_MOD_X_READY) { + + UBYTE nsapi = 0; + + for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) { + if ((sndcp_data->mg.waiting_nsapis & (1 << nsapi)) > 0) { + +#ifdef SNDCP_UPM_INCLUDED + PALLOC (snsm_modify_res, SN_MODIFY_CNF); +#else + PALLOC (snsm_modify_res, SNSM_MODIFY_RES); +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + snsm_modify_res->nsapi = nsapi; +#ifdef SNDCP_UPM_INCLUDED + PSEND(hCommUPM, snsm_modify_res); +#else + PSEND(hCommSM, snsm_modify_res); +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + } + } + sndcp_data->mg.waiting_nsapis = 0; + sndcp_data->mg.mod_expects = MG_MOD_X_NONE; + } +} /* mg_mod_res_if_nec() */ + +/* ++------------------------------------------------------------------------------ +| Function : mg_mod_sapi_diff ++------------------------------------------------------------------------------ +| Description : An snsm_modify_ind has indicated that the new sapi for the +| affected context is different from the current one. +| +| Parameters : snsm_modify_ind +| ++------------------------------------------------------------------------------ +*/ +#ifdef SNDCP_UPM_INCLUDED +LOCAL void mg_mod_sapi_diff (T_SN_MODIFY_REQ* snsm_modify_ind) { +#else +LOCAL void mg_mod_sapi_diff (T_SNSM_MODIFY_IND* snsm_modify_ind) { +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + BOOL old_sapi_ack = FALSE; + BOOL alone = TRUE; + BOOL new_context_ack = FALSE; + BOOL new_context_ack_spec = FALSE; + BOOL new_sapi_est = FALSE; + UBYTE nsapi = 0; + UBYTE old_sapi = 0; + BOOL rec = FALSE; + UBYTE old_sapi_index, new_sapi_index = 0; + T_SN_UNITDATA_IND *temp_sn_unitdata = NULL; + + TRACE_FUNCTION( "mg_mod_sapi_diff" ); + + /* + * If old sapi was established and affected nsapi is only one connected + * in ack mode: LL_RELEASE_IND expected. + */ + sndcp_get_sapi_ack(snsm_modify_ind->sapi, &old_sapi_ack); + while (nsapi < SNDCP_NUMBER_OF_NSAPIS && alone) { + + UBYTE sapi = 0; + BOOL ack = FALSE; + + sndcp_get_nsapi_sapi(nsapi, &sapi); + sndcp_get_nsapi_ack(nsapi, &ack); + alone = ! (nsapi != snsm_modify_ind->nsapi && + sapi == snsm_modify_ind->sapi && + ack); + + + nsapi++; + } + + /* + * If new qos is ack and new sapi is not yet established: expect + * LL_ESTABLISH_IND. + */ + mg_is_ack(snsm_modify_ind->snsm_qos, + &new_context_ack_spec, + &new_context_ack); + + if (alone && !new_context_ack) { + sndcp_data->mg.mod_expects |= MG_MOD_X_REL; + } + + + sndcp_get_sapi_ack(snsm_modify_ind->sapi, &new_sapi_est); + if (! new_sapi_est) { + sndcp_data->mg.mod_expects |= MG_MOD_X_EST; + } + + /* Old & the New SAPI are UnAck Mode, send SNSM_MOD_CNF to SM and + * flowcontrol to LLC + */ + sndcp_get_nsapi_sapi(snsm_modify_ind->nsapi, &old_sapi); + sndcp_get_sapi_ack(old_sapi, &old_sapi_ack); + if(new_context_ack == old_sapi_ack && old_sapi_ack == FALSE) + { + sndcp_get_sapi_index(old_sapi, &old_sapi_index); + sndcp_data->sd = & sndcp_data->sd_base[old_sapi_index]; + sd_is_nsapi_rec(snsm_modify_ind->nsapi, &rec); + + /* Copy the Pointer, where Data on old Sapi was stored if any */ + if(sndcp_data->sd->cur_sn_unitdata_ind[snsm_modify_ind->nsapi] NEQ NULL) + { + temp_sn_unitdata = + sndcp_data->sd->cur_sn_unitdata_ind[snsm_modify_ind->nsapi]; + sndcp_data->sd->cur_sn_unitdata_ind[snsm_modify_ind->nsapi] = NULL; + } + + /* Set the old SAPI's NSAPI state to Non Receptive*/ + sd_set_nsapi_rec(snsm_modify_ind->nsapi, FALSE); + + /* Set the state of NSAPI associated with new SAPI same as Old SAPI */ + sndcp_get_sapi_index(snsm_modify_ind->sapi, &new_sapi_index); + sndcp_data->sd = & sndcp_data->sd_base[new_sapi_index]; + sd_set_nsapi_rec(snsm_modify_ind->nsapi, rec); + + sndcp_data->mg.mod_expects = MG_MOD_X_READY; + + /* + * Taking care of DOWNLINK Data, when PDP is Modified + * from one sapi to another. + */ + switch( sndcp_get_nsapi_rec_state(snsm_modify_ind->nsapi) ) + { + case SD_UNACK_RECEIVE_SUBSEQUENT_SEGMENT: + /* + * If the Receiving State is SD_UNACK_RECEIVE_SUBSEQUENT_SEGMENT, + * this means that SNDCP has not receive the whole N-PDU, + * it has received some SN-PDU's of the whole N-PDU. + * Hence we need to DELETE those SN-PDU's since PDP gets modified. + */ + sig_mg_cia_delete_npdus(snsm_modify_ind->nsapi); + sndcp_set_nsapi_rec_state(snsm_modify_ind->nsapi, + SD_UNACK_RECEIVE_FIRST_SEGMENT); + break; + + case SD_UNACK_WAIT_NSAPI: + /* + * If the Receiving State is SD_UNACK_WAIT_NSAPI, this means that + * SNDCP has received the whole N-PDU. + * Since SNDCP has not received the FLOW CONTROL from application, + * so it could not send the N-PDU to the application. + * In the meantime PDP gets modified.In this condition SNDCP needs + * to copy the N-PDU from the old sapi to the modified sapi. + */ + if(temp_sn_unitdata NEQ NULL) + { + sndcp_data->sd->cur_sn_unitdata_ind[snsm_modify_ind->nsapi] + = temp_sn_unitdata; + } + break; + + default: + /* + * It is assumed that if the Receiving State is SD_UNACK_DISCARD + * then SNDCP must have deleted all the SN-PDU,s that it might + * have received on the old sapi. Hence we need not have to do + * anything here. + */ + break; + } + + /* Flowcontrol to LLC for new SAPI to send downlink data after + * PDP Modification + */ + if(sndcp_data->sd->cur_sn_unitdata_ind[snsm_modify_ind->nsapi] EQ NULL) + { + sd_get_unitdata_if_nec(snsm_modify_ind->sapi); + } + } + /* + * Now switch to the new setting. + */ + sndcp_set_nsapi_sapi(snsm_modify_ind->nsapi, snsm_modify_ind->sapi); + +} /* mg_mod_sapi_diff() */ + +/* ++------------------------------------------------------------------------------ +| Function : mg_mod_unack_ack ++------------------------------------------------------------------------------ +| Description : An snsm_modify_ind has indicated that the operation mode of +| the affected nsapi changed from unacknowledged to acknowledged. +| +| Parameters : snsm_modify_ind +| ++------------------------------------------------------------------------------ +*/ +#ifdef SNDCP_UPM_INCLUDED +LOCAL void mg_mod_unack_ack (T_SN_MODIFY_REQ* snsm_modify_ind) { +#else +LOCAL void mg_mod_unack_ack (T_SNSM_MODIFY_IND* snsm_modify_ind) { +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + BOOL ack = FALSE; + + TRACE_FUNCTION( "mg_mod_unack_ack" ); + + mg_delete_npdus(snsm_modify_ind->nsapi); + sndcp_set_nsapi_ack(snsm_modify_ind->nsapi, TRUE); + sig_mg_nu_reset_ack(snsm_modify_ind->nsapi, 0, 0, TRUE); + /* + * LL_ESTABLISH_IND expected, if the sapi is not in established mode. + */ + sndcp_get_sapi_ack(snsm_modify_ind->sapi, &ack); + if (! ack) { + sndcp_data->mg.mod_expects |= MG_MOD_X_EST; + } +} /* mg_mod_unack_ack() */ + + +/* ++------------------------------------------------------------------------------ +| Function : mg_start_re_est_timer ++------------------------------------------------------------------------------ +| Description : According to GSM 4.65, 6.2.1.4, starts re-establishment timer +| +| Parameters : affected sapi +| ++------------------------------------------------------------------------------ +*/ +LOCAL void mg_start_re_est_timer (UBYTE sapi) { + UBYTE sapi_index = 0; + + TRACE_FUNCTION( "mg_start_re_est_timer" ); + + sndcp_get_sapi_index(sapi, &sapi_index); + vsi_t_start(SNDCP_handle, sapi_index, MG_RE_EST_TIME); + +} /* mg_start_re_est_timer() */ + + + + +/*==== PUBLIC FUNCTIONS =====================================================*/ + + +/* ++------------------------------------------------------------------------------ +| Function : mg_exp_re_est_timer ++------------------------------------------------------------------------------ +| Description : Re establishment timer has expired +| +| Parameters : sapi_index +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void mg_exp_re_est_timer (UBYTE sapi_index) +{ + TRACE_FUNCTION( "mg_exp_re_est_timer" ); + + sndcp_data->su = & sndcp_data->su_base[sapi_index]; +#ifdef SNDCP_UPM_INCLUDED + mg_re_negotiate_ack(sndcp_data->su->sapi, + CAUSE_SN_NO_PEER_RESPONSE); +#else + mg_re_negotiate_ack(sndcp_data->su->sapi, + LL_RELCS_NO_PEER_RES); +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + +} /* mg_exp_re_est_timer() */ + +/* ++------------------------------------------------------------------------------ +| Function : mg_ll_reset_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive LL_RESET_IND +| +| Parameters : *ll_reset_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void mg_ll_reset_ind ( T_LL_RESET_IND *ll_reset_ind ) +{ + UBYTE nsapi = 0; + UBYTE sapi_index = 0; + BOOL ack = FALSE; + UBYTE sapi = 0; + + TRACE_FUNCTION( "mg_ll_reset_ind" ); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS;nsapi++) { + BOOL used = 0; + + sndcp_is_nsapi_used(nsapi, &used); + if (! used) { + continue; + } + sig_mg_nu_reset_ind(nsapi); + sig_mg_nu_suspend(nsapi); + + sndcp_get_nsapi_sapi(nsapi, &sapi); + sndcp_get_nsapi_ack(nsapi, &ack); + + if (ack) { + sig_mg_sua_delete_pdus(nsapi, sapi, FALSE); + sig_mg_sda_reset_ind(nsapi); + sig_mg_nd_suspend(nsapi); + sndcp_set_nsapi_state(nsapi, MG_SEQ); + /* Set the flag as LL_ESTB_IND is expected + * before resend of buffered NPDU + */ + sndcp_set_sapi_state(sapi, MG_EST_IND); + } else { + sig_mg_su_delete_pdus(nsapi, sapi); + sig_mg_sd_reset_ind(nsapi); + } + sig_mg_nd_reset_ind(nsapi); + } + sig_mg_cia_reset_ind(); + /* + * Reset pending states and xid_block. + */ + for (sapi_index = 0; sapi_index < SNDCP_NUMBER_OF_SAPIS; sapi_index++) { + + sapi = (sndcp_data->sua_base[sapi_index]).sapi; + /* + * Reset SUA and SU services + */ + sig_mg_sua_n201(sapi, N201_I_DEFAULT); + sig_mg_sua_reset_ind(sapi); + sig_mg_su_n201(sapi, N201_U_DEFAULT); + sig_mg_su_reset_ind(sapi); + /* + * cnf_xid_block and req_xid_block initialized. + */ + sndcp_reset_xid_block(&sndcp_data->mg.cnf_xid_block[sapi_index]); + sndcp_reset_xid_block(&sndcp_data->mg.req_xid_block[sapi_index]); + + mg_reset_states_n_rej(sapi_index); + /* + * Init renegotiation counter and cur_xid_block with default values. + */ + sndcp_data->mg.renego[sapi_index] = 0; + + sndcp_reset_xid_block(&sndcp_data->mg.cur_xid_block[sapi_index]); + sig_mg_cia_new_xid (&sndcp_data->mg.cur_xid_block[sapi_index]); + } + sndcp_data->mg.mod_expects = MG_MOD_X_NONE; + sndcp_data->mg.waiting_nsapis = 0; + + break; + default: + TRACE_ERROR( "LL_RESET_IND unexpected" ); + break; + } + if (ll_reset_ind != NULL) { + PFREE (ll_reset_ind); + } + +} /* mg_ll_reset_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : mg_ll_establish_cnf ++------------------------------------------------------------------------------ +| Description : Handles the primitive LL_ESTABLISH_CNF +| +| Parameters : *ll_establish_cnf - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void mg_ll_establish_cnf ( T_LL_ESTABLISH_CNF *ll_establish_cnf ) +{ + UBYTE sapi_index = 0; + USHORT state = 0; + + TRACE_FUNCTION( "mg_ll_establish_cnf" ); + TRACE_EVENT_P1("ll_establish_cnf->n201_i: %d", ll_establish_cnf->n201_i); + + sndcp_get_sapi_index(ll_establish_cnf->sapi, &sapi_index); + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + sndcp_get_sapi_state(ll_establish_cnf->sapi, &state); + if ((state & MG_EST) > 0) { + + UBYTE dec_ret = 0; + UBYTE check_ret = 0; + + /* + * Reset all compressors at this SAPI in ack mode. + */ + mg_reset_comp_ack(ll_establish_cnf->sapi); + /* + * Set N201 values in uplink services. + */ + sig_mg_su_n201(ll_establish_cnf->sapi, ll_establish_cnf->n201_u); + sig_mg_sua_n201(ll_establish_cnf->sapi, ll_establish_cnf->n201_i); + + /* + * SDL label MG_EST_CNF_EST_XID_PENDING. + */ + mg_decode_xid(&(ll_establish_cnf->sdu), + &(sndcp_data->mg.cnf_xid_block[sapi_index]), + &dec_ret, + ll_establish_cnf->sapi); + if (dec_ret == MG_XID_OK) + { + /* + * SDL label MG_CHECK_CNF_XID_ACK + */ + mg_check_cnf_xid(&check_ret, ll_establish_cnf->sapi); + if (check_ret == MG_XID_OK) + { + + /* + * This is now similar to the reaction to LL_XID_CNF: + */ + /* + * SDL Label MG_CNF_OK_ACK + */ + mg_set_cur_xid_block(ll_establish_cnf->sapi); + /* + * Reset nsapis or ntts that were assigned, but are not any more. + */ + mg_clean_xid(ll_establish_cnf->sapi); + /* + * Resume suspended data transfer on sapi will be done in + * mg_est_cnf_est_pending(ll_establish_cnf). + */ + + mg_est_cnf_est_pending(ll_establish_cnf); + + sndcp_get_sapi_state(ll_establish_cnf->sapi, &state); + if (((state & MG_XID_NEC) > 0) + && + ((state & MG_REL) == 0)) { + mg_resend_xid_if_nec(ll_establish_cnf->sapi); + } + + } else { + #ifdef SNDCP_UPM_INCLUDED + mg_re_negotiate_ack(ll_establish_cnf->sapi, + CAUSE_SN_INVALID_XID); + #else + mg_re_negotiate_ack(ll_establish_cnf->sapi, + SNSM_RELCS_INVALID_XID); + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + } + } else { + #ifdef SNDCP_UPM_INCLUDED + mg_re_negotiate_ack(ll_establish_cnf->sapi, + CAUSE_SN_INVALID_XID); + #else + mg_re_negotiate_ack(ll_establish_cnf->sapi, + SNSM_RELCS_INVALID_XID); + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + } + break; + + } else { /* if ((state & MG_EST) > 0) */ + + PALLOC(ll_release_req, LL_RELEASE_REQ); + + sndcp_unset_sapi_state(ll_release_req->sapi, MG_REL_NEC_PEER); + ll_release_req->sapi = ll_establish_cnf->sapi; + ll_release_req->local = FALSE; + /* + * Set the "state" for the affected sapi to MG_REL. + */ + sndcp_set_sapi_state(ll_establish_cnf->sapi, MG_REL); + + PSEND(hCommLLC, ll_release_req); + } + break; + default: + TRACE_ERROR( "LL_ESTABLISH_CNF unexpected" ); + break; + } + + /* + * Establish confirm has been computed. If no new XID is pending, + * the req_xid_block may be reset. + */ + sndcp_get_sapi_state(ll_establish_cnf->sapi, &state); + if (((state & MG_XID) == 0) && + ((state & MG_EST) == 0)) { + sndcp_reset_xid_block(&sndcp_data->mg.req_xid_block[sapi_index]); + } + + if (ll_establish_cnf != NULL) { + PFREE(ll_establish_cnf); + } + +} /* mg_ll_establish_cnf() */ + + +/* ++------------------------------------------------------------------------------ +| Function : mg_ll_status_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive LL_STATUS_IND +| +| Parameters : *ll_status_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void mg_ll_status_ind ( T_LL_STATUS_IND *ll_status_ind ) +{ + USHORT sapi_state = MG_IDLE; + + TRACE_FUNCTION( "mg_ll_status_ind" ); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + { + #ifdef SNDCP_UPM_INCLUDED + PALLOC(snsm_status_req, SN_STATUS_IND); + #else + PALLOC(snsm_status_req, SNSM_STATUS_REQ); + #endif + snsm_status_req->sapi = ll_status_ind->sapi; + +#ifdef SNDCP_UPM_INCLUDED + snsm_status_req->ps_cause.ctrl_value = CAUSE_is_from_llc; + snsm_status_req->ps_cause.value.llc_cause = +#ifdef SNDCP_2to1 + mg_ll_status_to_snsm_status(ll_status_ind->ps_cause.value.llc_cause); +#else /*SNDCP_2to1*/ + mg_ll_status_to_snsm_status(ll_status_ind->error_cause); +#endif /*SNDCP_2to1*/ + + PSEND(hCommUPM, snsm_status_req); + +#else /*SNDCP_UPM_INCLUDED*/ + snsm_status_req->status_cause = + #ifdef _SNDCP_DTI_2_ + mg_ll_status_to_snsm_status(ll_status_ind->error_cause); + #else /* _SNDCP_DTI_2_ */ + (U8)mg_ll_status_to_snsm_status(ll_status_ind->error_cause); + #endif /* _SNDCP_DTI_2_ */ + + PSEND(hCommSM, snsm_status_req); +#endif /*SNDCP_UPM_INCLUDED*/ + sndcp_get_sapi_state(ll_status_ind->sapi, &sapi_state); + if ((sapi_state & MG_XID) != 0) + { + sig_mg_su_resume(ll_status_ind->sapi); + sig_mg_sua_resume(ll_status_ind->sapi); + mg_resume_affected_nus(ll_status_ind->sapi); + sndcp_unset_sapi_state (ll_status_ind->sapi, MG_XID); + } + if ((sapi_state & MG_EST) != 0) + { +#ifdef SNDCP_UPM_INCLUDED + if (snsm_status_req->ps_cause.value.llc_cause == + CAUSE_LLC_NO_PEER_RES) { +#else /* SNDCP_UPM_INCLUDED */ +#ifdef _SNDCP_DTI_2_ + if (snsm_status_req->status_cause == LL_RELCS_NO_PEER_RES) { +#else /*_SNDCP_DTI_2_*/ + if (snsm_status_req->status_cause == SNSM_RELCS_NO_PEER_RES) { +#endif /* _SNDCP_DTI_2_*/ +#endif /* SNDCP_UPM_INCLUDED */ + mg_start_re_est_timer(ll_status_ind->sapi); + } else { + sig_mg_su_resume(ll_status_ind->sapi); + sig_mg_sua_resume(ll_status_ind->sapi); + mg_resume_affected_nus(ll_status_ind->sapi); + sndcp_unset_sapi_state (ll_status_ind->sapi, MG_EST); + } + } + } + break; + default: + TRACE_ERROR( "LL_STATUS_IND unexpected" ); + break; + } + + if (ll_status_ind != NULL) { + PFREE(ll_status_ind); + } + +} /* mg_ll_status_ind() */ + + +/* ++------------------------------------------------------------------------------ +| Function : mg_ll_establish_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive LL_ESTABLISH_IND +| +| Parameters : *ll_establish_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void mg_ll_establish_ind ( T_LL_ESTABLISH_IND *ll_establish_ind ) +{ + USHORT sapi_state = 0; + + TRACE_FUNCTION( "mg_ll_establish_ind" ); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + sndcp_unset_sapi_state(ll_establish_ind->sapi, MG_EST_IND); + /* + * Reset all compressors at this SAPI in ack mode. + */ + mg_reset_comp_ack(ll_establish_ind->sapi); + /* + * If prim has been expected in course of modification, here it is. + */ + sndcp_data->mg.mod_expects &= ~ MG_MOD_X_EST; + /* + * Do we have a collision? + */ + sndcp_get_sapi_state(ll_establish_ind->sapi, &sapi_state); + if ((sapi_state & MG_REL) > 0) { + + PFREE(ll_establish_ind); + return; + } + + + if (((sapi_state & MG_XID) > 0) + || + ((sapi_state & MG_EST) > 0)) { + /* + * Is the establishment a re-establishment? + */ + BOOL re = FALSE; + + sndcp_get_sapi_ack(ll_establish_ind->sapi, &re); + if (re) { + mg_col_re(ll_establish_ind); + } else { + mg_col_no_re(ll_establish_ind); + } + } else { + /* + * Is the establishment a re-establishment? + */ + BOOL re = FALSE; + + sndcp_get_sapi_ack(ll_establish_ind->sapi, &re); + if (re) { + mg_no_col_re(ll_establish_ind); + } else { + mg_no_col_no_re(ll_establish_ind); + } + } + /* + * Now send snsm_modify_res, if expected. + */ + mg_mod_res_if_nec(); + break; + default: + TRACE_ERROR( "LL_ESTABLISH_IND unexpected" ); + break; + } + if (ll_establish_ind != NULL) { + PFREE(ll_establish_ind); + } + +} /* mg_ll_establish_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : mg_ll_release_cnf ++------------------------------------------------------------------------------ +| Description : Handles the primitive LL_RELEASE_CNF +| +| Parameters : *ll_release_cnf - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void mg_ll_release_cnf ( T_LL_RELEASE_CNF *ll_release_cnf ) +{ + UBYTE nsapi = 0; + USHORT nsapi_state = MG_IDLE; + UBYTE sapi = 0; + USHORT sapi_state = MG_IDLE; + + TRACE_FUNCTION( "mg_ll_release_cnf" ); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + /* + * Reset all compressors at this SAPI in ack mode. + */ + mg_reset_comp_ack(ll_release_cnf->sapi); + + for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) { + sndcp_get_nsapi_state(nsapi, &nsapi_state); + sndcp_get_nsapi_sapi(nsapi, &sapi); + sndcp_get_sapi_state(ll_release_cnf->sapi, &sapi_state); + if (((sapi_state & MG_REL) > 0 ) + && + ((nsapi_state & MG_DEACT) > 0 ) + && + ((sapi_state & MG_XID) == 0 )) { + /* + * Release is now completed, negotiate XID or deactivate context. + */ + if (sapi == ll_release_cnf->sapi) { + BOOL nec = FALSE; + + mg_is_rel_comp_nec(nsapi, &nec); + if (nec) { + sndcp_set_sapi_state(sapi, MG_XID_NEC); + sndcp_get_sapi_state(sapi, &sapi_state); + } else { + #ifdef SNDCP_UPM_INCLUDED + PALLOC(snsm_deactivate_res, SN_DEACTIVATE_CNF); + snsm_deactivate_res->nsapi = nsapi; + #else + PALLOC(snsm_deactivate_res, SNSM_DEACTIVATE_RES); + snsm_deactivate_res->nsapi = nsapi; + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + /* + * Now the NSAPI is not in use anymore: + */ + sndcp_set_nsapi_used(nsapi, FALSE); + sndcp_set_nsapi_ack(nsapi, FALSE); + /* + * Set the "state" of the nsapi. + */ + sndcp_unset_nsapi_state(nsapi, MG_DEACT); + +#ifdef SNDCP_UPM_INCLUDED + PSEND(hCommUPM, snsm_deactivate_res); +#else /*#ifdef SNDCP_UPM_INCLUDED*/ + PSEND(hCommSM, snsm_deactivate_res); +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + } + } + } + if (((sapi_state & MG_REL) > 0 ) + && + ((nsapi_state & MG_DEACT) > 0 ) + && + ((sapi_state & MG_XID_NEC) > 0 )) { + /* + * Release is now completed, + * Remove nspi from compressor. + */ + /* + * Suspend uplink transfer for affected sapi. + */ + sig_mg_su_suspend(sapi); + sig_mg_sua_suspend(sapi); + mg_suspend_affected_nus(sapi); + /* + * Negotiate possible deactivation of compressors. + */ + mg_send_xid_req_del(sapi); + } + } + sndcp_set_sapi_ack(ll_release_cnf->sapi, FALSE); + sndcp_unset_sapi_state(ll_release_cnf->sapi, MG_REL); + break; + default: + TRACE_ERROR( "LL_RELEASE_CNF unexpected" ); + break; + } + if (ll_release_cnf != NULL) { + PFREE(ll_release_cnf); + } + +} /* mg_ll_release_cnf() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : mg_ll_release_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive LL_RELEASE_IND +| +| Parameters : *ll_release_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void mg_ll_release_ind ( T_LL_RELEASE_IND *ll_release_ind ) +{ + + USHORT sapi_state = 0; + U8 sapi_index = 0; + + TRACE_FUNCTION( "mg_ll_release_ind" ); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + + sndcp_unset_sapi_state(ll_release_ind->sapi, + MG_REL_NEC_LOC + MG_REL_NEC_PEER); + sndcp_get_sapi_state(ll_release_ind->sapi, &sapi_state); + + /* + * Service sda may now leave state SDA_ESTABLISH_REQUESTED. + */ + sig_mg_sda_end_est(ll_release_ind->sapi, FALSE); + +#ifdef SNDCP_2to1 + if (((sapi_state & MG_EST) > 0) && + ((ll_release_ind->ps_cause.ctrl_value == CAUSE_is_from_llc) && + (ll_release_ind->ps_cause.value.llc_cause == CAUSE_LLC_NO_PEER_RES))) +#else /*SNDCP_2to1*/ + if (((sapi_state & MG_EST) > 0) && + (ll_release_ind->cause == LL_RELCS_NO_PEER_RES)) +#endif /*SNDCP_2to1*/ + { + + /* + * SNDCP waits for LL_ESTABLISH_CNF and cause is "no peer response". + * According to GSM 4.65, 6.2.1.4 a re-establishment is tried after an + * implementation specific amount of time. + */ + mg_start_re_est_timer(ll_release_ind->sapi); + PFREE(ll_release_ind); + return; + } + + sndcp_unset_sapi_state(ll_release_ind->sapi, MG_EST); + + + if ((sapi_state & MG_REL) > 0) { + + /* + * SNDCP waits for LL_ESTABLISH_CNF and cause is "no peer response". + * According to GSM 4.65, 6.2.1.4 a re-establishment is tried after an + * implementation specific amount of time. + */ + PALLOC (ll_release_cnf, LL_RELEASE_CNF); + ll_release_cnf->sapi = ll_release_ind->sapi; + mg_ll_release_cnf(ll_release_cnf); + PFREE(ll_release_ind); + return; + } + + /* + * Reset all compressors at this SAPI in ack mode. + */ + mg_reset_comp_ack(ll_release_ind->sapi); + /* + * If release has been expected in course of modification, here it is. + */ + if ((sndcp_data->mg.mod_expects & MG_MOD_X_REL) > 0) { + sndcp_data->mg.mod_expects -= MG_MOD_X_REL; + } + mg_del_comp_pdus_ack(ll_release_ind->sapi); + sig_mg_su_resume(ll_release_ind->sapi); + sig_mg_sua_resume(ll_release_ind->sapi); + mg_resume_affected_nus(ll_release_ind->sapi); +#ifdef SNDCP_2to1 + if (((ll_release_ind->ps_cause.ctrl_value == CAUSE_is_from_llc)&& + (ll_release_ind->ps_cause.value.llc_cause == CAUSE_LLC_DM_RECEIVED)) || + ((ll_release_ind->ps_cause.ctrl_value == CAUSE_is_from_llc)&& + (ll_release_ind->ps_cause.value.llc_cause == CAUSE_LLC_INVALID_XID)) || + ((ll_release_ind->ps_cause.ctrl_value == CAUSE_is_from_llc)&& + (ll_release_ind->ps_cause.value.llc_cause == CAUSE_LLC_NO_PEER_RES))) { +#else /*SNDCP_2to1*/ + if (ll_release_ind->cause == LL_RELCS_DM_RECEIVED || + ll_release_ind->cause == LL_RELCS_INVALID_XID || + ll_release_ind->cause == LL_RELCS_NO_PEER_RES) { +#endif /*SNDCP_2to1*/ + +#ifdef SNDCP_UPM_INCLUDED + PALLOC (snsm_status_req, SN_STATUS_IND); +#ifdef SNDCP_2to1 + if((ll_release_ind->ps_cause.ctrl_value == CAUSE_is_from_llc)&& + (ll_release_ind->ps_cause.value.llc_cause == CAUSE_LLC_DM_RECEIVED)){ +#else + if (ll_release_ind->cause == LL_RELCS_DM_RECEIVED){ +#endif + UBYTE nsapi, sapi = 0; + USHORT nsapi_set = 0; + for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++){ + sndcp_get_nsapi_sapi(nsapi, &sapi); + if(sapi == ll_release_ind->sapi){ + BOOL ack = FALSE; + sndcp_get_nsapi_ack(nsapi, &ack); + if(ack){ + nsapi_set |= (1 << nsapi); + } + } + } + snsm_status_req->nsapi_set = nsapi_set; + } + snsm_status_req->sapi = ll_release_ind->sapi; + snsm_status_req->ps_cause.ctrl_value = CAUSE_is_from_llc; + snsm_status_req->ps_cause.value.llc_cause = +#ifdef SNDCP_2to1 + mg_ll_release_to_snsm_status(ll_release_ind->ps_cause.value.llc_cause); +#else /*SNDCP_2to1*/ + mg_ll_release_to_snsm_status(ll_release_ind->cause); +#endif /*SNDCP_2to1*/ + PSEND(hCommUPM, snsm_status_req); +#else /* SNDCP_UPM_INCLUDED */ + PALLOC (snsm_status_req, SNSM_STATUS_REQ); + snsm_status_req->sapi = ll_release_ind->sapi; + snsm_status_req->status_cause = + #ifdef _SNDCP_DTI_2_ + mg_ll_release_to_snsm_status(ll_release_ind->cause); + #else /* _SNDCP_DTI_2_ */ + (U8)mg_ll_release_to_snsm_status(ll_release_ind->cause); + #endif /* _SNDCP_DTI_2_ */ + + PSEND(hCommSM, snsm_status_req); +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + + } + sndcp_set_sapi_ack(ll_release_ind->sapi, FALSE); + + /* + * Now send snsm_modify_res, if expected. + */ + mg_mod_res_if_nec(); + break; + default: + TRACE_ERROR( "LL_RELEASE_IND unexpected" ); + break; + } + /* + * Establish confirm has been computed. If no new XID is pending, + * the req_xid_block may be reset. + */ + sndcp_get_sapi_index(ll_release_ind->sapi, &sapi_index); + sndcp_get_sapi_state(ll_release_ind->sapi, &sapi_state); + if (((sapi_state & MG_XID) == 0) && + ((sapi_state & MG_EST) == 0)) { + sndcp_reset_xid_block(&sndcp_data->mg.req_xid_block[sapi_index]); + } + + if (ll_release_ind != NULL) { + PFREE(ll_release_ind); + } + +} /* mg_ll_release_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : mg_ll_xid_cnf ++------------------------------------------------------------------------------ +| Description : Handles the primitive LL_XID_CNF +| +| Parameters : *ll_xid_cnf - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void mg_ll_xid_cnf ( T_LL_XID_CNF* ll_xid_cnf ) +{ + UBYTE dec_ret = 0; + UBYTE check_ret = 0; + UBYTE sapi_index = 0; + + TRACE_FUNCTION( "mg_ll_xid_cnf" ); + + sndcp_get_sapi_index(ll_xid_cnf->sapi, &sapi_index); + +#ifdef SNDCP_TRACE_ALL + TRACE_EVENT("incoming xid block:"); + sndcp_trace_sdu(&ll_xid_cnf->sdu); +#endif + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + + sndcp_unset_sapi_state(ll_xid_cnf->sapi, MG_XID); + + mg_decode_xid(&(ll_xid_cnf->sdu), + &(sndcp_data->mg.cnf_xid_block[sapi_index]), + &dec_ret, + ll_xid_cnf->sapi); + if (dec_ret == MG_XID_OK) { + mg_check_cnf_xid(&check_ret, ll_xid_cnf->sapi); + if (check_ret == MG_XID_OK) { + USHORT sapi_state = MG_IDLE; + + /* + * SDL Label MG_CNF_OK + */ + mg_set_cur_xid_block(ll_xid_cnf->sapi); + mg_xid_cnf_ok_res(ll_xid_cnf->sapi); + /* + * Reset nsapis or ntts that were assigned, but are not any more. + */ + mg_clean_xid(ll_xid_cnf->sapi), + /* + * Set n201. + */ + sig_mg_su_n201 (ll_xid_cnf->sapi, ll_xid_cnf->n201_u); + sig_mg_sua_n201 (ll_xid_cnf->sapi, ll_xid_cnf->n201_i); + + /* + * Resume suspended data transfer on sapi. + */ + + sndcp_get_sapi_state(ll_xid_cnf->sapi, &sapi_state); + if (((sapi_state & MG_XID) == 0) + && + ((sapi_state & MG_EST) == 0)) { + + sig_mg_su_resume(ll_xid_cnf->sapi); + sig_mg_sua_resume(ll_xid_cnf->sapi); + mg_resume_affected_nus(ll_xid_cnf->sapi); + } + + /* + * Now get downlink data. + */ + + mg_get_downlink_data(ll_xid_cnf->sapi); + + /* + * XID confirm has been computed. The negotiation is finished and + * the req_xid_block may be reset. + */ + sndcp_get_sapi_state(ll_xid_cnf->sapi, &sapi_state); + if (((sapi_state & MG_XID) == 0) && + ((sapi_state & MG_EST) == 0)) { + sndcp_reset_xid_block(&sndcp_data->mg.req_xid_block[sapi_index]); + } + } else { + mg_re_negotiate(ll_xid_cnf->sapi); + } + } else { + mg_re_negotiate(ll_xid_cnf->sapi); + } + break; + default: + TRACE_ERROR( "LL_XID_CNF unexpected" ); + break; + } + if (ll_xid_cnf != NULL) { + PFREE(ll_xid_cnf); + sndcp_reset_xid_block(&sndcp_data->mg.cnf_xid_block[sapi_index]); + } + +} /* mg_ll_xid_cnf() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : mg_ll_xid_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive LL_XID_IND +| +| Parameters : *ll_xid_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void mg_ll_xid_ind ( T_LL_XID_IND *ll_xid_ind ) +{ + UBYTE dec_ret = 0; + UBYTE check_ret = 0; + UBYTE sapi_index = 0; + + TRACE_FUNCTION( "mg_ll_xid_ind" ); + + sndcp_get_sapi_index(ll_xid_ind->sapi, &sapi_index); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + + /* + * Set N201 values in uplink services. + */ + sig_mg_su_n201(ll_xid_ind->sapi, ll_xid_ind->n201_u); + sig_mg_sua_n201(ll_xid_ind->sapi, ll_xid_ind->n201_i); + + TRACE_EVENT_P3("l3_valid: %d, N201_I: %d, N201_U: %d", + ll_xid_ind->xid_valid, ll_xid_ind->n201_i, + ll_xid_ind->n201_i); + + /* + * If SNDCP XID block is not valid, we are ready. + */ + if (ll_xid_ind->xid_valid == LL_XID_INVALID) { + break; + } + /* + * SNDCP XID block is valid and checked now. + */ + mg_decode_xid(&(ll_xid_ind->sdu), + &(sndcp_data->mg.ind_xid_block[sapi_index]), + &dec_ret, + ll_xid_ind->sapi); + if (dec_ret == MG_XID_OK) { + mg_check_ind_xid(&check_ret, ll_xid_ind->sapi); + if (check_ret == MG_XID_OK) { + /* + * Label MG_IND_OK + */ + USHORT res_sdu_bit_len = 0; + UBYTE ntt = 0; + BOOL v42_rej = FALSE; + BOOL vj_rej = FALSE; + USHORT sapi_state = MG_IDLE; + + mg_set_res_cur_xid_block(ll_xid_ind->sapi, &res_sdu_bit_len); + + /* + * Add the extra space for ntts with nsapis == 0. + */ + for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) { + BOOL rej = FALSE; + + mg_get_sapi_dntt_rej(ll_xid_ind->sapi, ntt, &rej); + if (rej) { + /* + * length of ntt octet and nsapis. + */ + res_sdu_bit_len += 32; + v42_rej = TRUE; + } + mg_get_sapi_pntt_rej(ll_xid_ind->sapi, ntt, &rej); + if (rej) { + /* + * length of ntt octet and nsapis. + */ + res_sdu_bit_len += 32; + vj_rej = TRUE; + } + } + if (! sndcp_data->mg.ind_xid_block[sapi_index].v42.is_set && + v42_rej) { + /* + * Add length of parameter type and length. + */ + res_sdu_bit_len += 16; + } + if (! sndcp_data->mg.ind_xid_block[sapi_index].vj.is_set && + vj_rej) { + /* + * Add length of parameter type and length. + */ + res_sdu_bit_len += 16; + } + + { + PALLOC_SDU (ll_xid_res, LL_XID_RES, res_sdu_bit_len); + + /* + * Set sapi in ll_xid_res. + */ + ll_xid_res->sapi = ll_xid_ind->sapi; + /* + * Write res_xid_block struct to sdu byte buffer. Implementation dep.. + */ + mg_set_res_xid_params(&ll_xid_res->sdu, ll_xid_ind->sapi); + /* + * Mark the affected nsapi and sapi as MG_XID_IDLE. + */ + sndcp_unset_sapi_state(ll_xid_ind->sapi, MG_XID); + sndcp_unset_sapi_state(ll_xid_ind->sapi, MG_EST); + + /* + * Send the XID block to LLC. + */ + +#ifdef SNDCP_RANGE_CHECK + + if(ll_xid_res EQ NULL) + { + TRACE_EVENT("ERROR: ll_xid_res is NULL"); + } + else if(*((ULONG*)ll_xid_res - 7) NEQ 0) + { + TRACE_EVENT("ERROR in SNDCP: ll_xid_res is not allocated"); + } + +#endif /* SNDCP_RANGE_CHECK */ + + PSEND(hCommLLC, ll_xid_res); + } + + /* + * Reset nsapis or ntts that were assigned, but are not any more. + */ + mg_clean_xid(ll_xid_ind->sapi); + + /* + * If there was a collision and xid has not been negotiated + * sufficiently. + */ + mg_resend_xid_if_nec(ll_xid_ind->sapi); + /* + * If activation or deactivation is pending, it will be responded if + * no xid_req is pending. + */ + sndcp_get_sapi_state(ll_xid_ind->sapi, &sapi_state); + if ((sapi_state & MG_XID) == 0) { + mg_xid_cnf_ok_res(ll_xid_ind->sapi); + } + + + } else { + /* + * not (check_ret == MG_IND_XID_OK) + */ + /* + * Label MG_CHECK_FAIL + */ + USHORT res_sdu_bit_len = 0; + UBYTE ntt = 0; + BOOL v42_rej = FALSE; + BOOL vj_rej = FALSE; + + /* + * Add the extra space for ntts with nsapis == 0. + */ + for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) { + BOOL rej = FALSE; + + mg_get_sapi_dntt_rej(ll_xid_ind->sapi, ntt, &rej); + if (rej) { + /* + * length of ntt octet and nsapis. + */ + res_sdu_bit_len += 32; + v42_rej = TRUE; + } + mg_get_sapi_pntt_rej(ll_xid_ind->sapi, ntt, &rej); + if (rej) { + /* + * length of ntt octet and nsapis. + */ + res_sdu_bit_len += 32; + vj_rej = TRUE; + } + } + if (v42_rej) { + /* + * Add length of parameter type and length. + */ + res_sdu_bit_len += 16; + } + if (vj_rej) { + /* + * Add length of parameter type and length. + */ + res_sdu_bit_len += 16; + } + /* + * Allocate response and send it. + */ + { + PALLOC_SDU (ll_xid_res, LL_XID_RES, res_sdu_bit_len); + + /* + * Reset res_xid_block, ind_xid_block. + */ + sndcp_reset_xid_block(&sndcp_data->mg.res_xid_block[sapi_index]); + sndcp_reset_xid_block(&sndcp_data->mg.ind_xid_block[sapi_index]); + /* + * Set sapi in ll_xid_res. + */ + ll_xid_res->sapi = ll_xid_ind->sapi; + /* + * Write res_xid_block struct to sdu byte buffer. Implementation dep.. + */ + mg_set_res_xid_params(&ll_xid_res->sdu, ll_xid_res->sapi); + /* + * Modify the affected sapi state. + */ + sndcp_unset_sapi_state(ll_xid_ind->sapi, MG_XID); + sndcp_unset_sapi_state(ll_xid_ind->sapi, MG_EST); + + /* + * Send the XID block to LLC. + */ + +#ifdef SNDCP_RANGE_CHECK + + if(ll_xid_res EQ NULL) + { + TRACE_EVENT("ERROR: ll_xid_res is NULL"); + } + else if(*((ULONG*)ll_xid_res - 7) NEQ 0) + { + TRACE_EVENT("ERROR in SNDCP: ll_xid_res is not allocated"); + } + +#endif /* SNDCP_RANGE_CHECK */ + + PSEND(hCommLLC, ll_xid_res); + } + /* + * If there was a collision and xid has not been negotiated + * sufficiently. + */ + mg_resend_xid_if_nec(ll_xid_ind->sapi); + + /* + * Reset nsapis or ntts that were assigned before + * but are not anymore. + */ + mg_clean_xid(ll_xid_ind->sapi); + /* + * Allocate status req and send it (label MG_SEND_STATUS_REQ). + */ + { +#ifdef SNDCP_UPM_INCLUDED + PALLOC (snsm_status_req, SN_STATUS_IND); + snsm_status_req->sapi = ll_xid_ind->sapi; + snsm_status_req->ps_cause.ctrl_value = CAUSE_is_from_sndcp; + snsm_status_req->ps_cause.value.sn_cause = CAUSE_SN_INVALID_XID; + PSEND(hCommUPM, snsm_status_req); +#else + PALLOC (snsm_status_req, SNSM_STATUS_REQ); + snsm_status_req->sapi = ll_xid_ind->sapi; + snsm_status_req->status_cause = SNSM_RELCS_INVALID_XID; + PSEND(hCommSM, snsm_status_req); +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + } + } + } else { /* not if (dec_ret == MG_XID_OK) */ + /* + * Reset nsapis or ntts that were assigned before + * but are not anymore. + */ + sndcp_reset_xid_block(&sndcp_data->mg.cur_xid_block[sapi_index]); + mg_clean_xid(ll_xid_ind->sapi); + /* + * Decoding of LL_XID_IND failed (label MG_SEND_STATUS_REQ). + * Allocate status req and send it. + */ + { + #ifdef SNDCP_UPM_INCLUDED + PALLOC (snsm_status_req, SN_STATUS_IND); + snsm_status_req->sapi = ll_xid_ind->sapi; + snsm_status_req->ps_cause.ctrl_value = CAUSE_is_from_sndcp; + snsm_status_req->ps_cause.value.sn_cause = CAUSE_SN_INVALID_XID; + PSEND(hCommUPM, snsm_status_req); + #else + PALLOC (snsm_status_req, SNSM_STATUS_REQ); + snsm_status_req->sapi = ll_xid_ind->sapi; + snsm_status_req->status_cause = SNSM_RELCS_INVALID_XID; + PSEND(hCommSM, snsm_status_req); + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + } + + } + break; + default: + TRACE_ERROR( "LL_XID_IND unexpected" ); + break; + } + if (ll_xid_ind != NULL) { + sndcp_reset_xid_block(&sndcp_data->mg.ind_xid_block[sapi_index]); + PFREE(ll_xid_ind); + } +} /* mg_ll_xid_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : mg_snsm_activate_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive SNSM_ACTIVATE_IND +| +| Parameters : *snsm_activate_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +#ifdef SNDCP_UPM_INCLUDED +GLOBAL void mg_snsm_activate_ind ( T_SN_ACTIVATE_REQ *snsm_activate_ind ) +#else +GLOBAL void mg_snsm_activate_ind ( T_SNSM_ACTIVATE_IND *snsm_activate_ind ) +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ +{ + /* + * is nsapi already used? + */ + BOOL used = FALSE; + /* + * is LLC mode specified (TRUE) or should the subscribed one be used + * (FALSE) + */ + BOOL spec = FALSE; + /* + * should the context use acknowledged LLC operation mode? + */ + BOOL b = FALSE; + + TRACE_FUNCTION( "mg_snsm_activate_ind" ); + +#ifndef NCONFIG + if (sndcp_data->millis > 0) { + vsi_t_sleep(VSI_CALLER sndcp_data->millis); + } +#endif /* NCONFIG */ + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + sndcp_is_nsapi_used(snsm_activate_ind->nsapi, &used); + if (used == FALSE) { + + USHORT sapi_state = MG_IDLE; + + sndcp_set_nsapi_state(snsm_activate_ind->nsapi, MG_ACT); + sndcp_reset_nd_nsapi_npdu_num(snsm_activate_ind->nsapi); + sndcp_set_nsapi_used(snsm_activate_ind->nsapi, TRUE); + sndcp_set_nsapi_qos(snsm_activate_ind->nsapi, + snsm_activate_ind->snsm_qos); + sndcp_set_nsapi_sapi(snsm_activate_ind->nsapi, + snsm_activate_ind->sapi); + sndcp_set_nsapi_prio(snsm_activate_ind->nsapi, + snsm_activate_ind->radio_prio); +#ifdef REL99 + sndcp_set_nsapi_pktflowid(snsm_activate_ind->nsapi, + snsm_activate_ind->pkt_flow_id); +#endif /*REL 99*/ + +#if 0 +#ifdef _SNDCP_DTI_2_ +#ifndef SNDCP_UPM_INCLUDED + if (snsm_activate_ind->dti_direction == DTI_CHANNEL_TO_LOWER_LAYER) { + /* new constant instead of SNSM HOME , replaced by DTI_CHANNEL_TO_LOWER_LAYER */ + sndcp_set_nsapi_direction(snsm_activate_ind->nsapi, DTI_CHANNEL_TO_LOWER_LAYER); + } else { + sndcp_set_nsapi_direction(snsm_activate_ind->nsapi, DTI_CHANNEL_TO_HIGHER_LAYER); + } + + sndcp_set_nsapi_linkid(snsm_activate_ind->nsapi, + snsm_activate_ind->dti_linkid); + + sndcp_set_nsapi_neighbor(snsm_activate_ind->nsapi, +#ifdef _SIMULATION_ + (snsm_activate_ind->dti_neighbor == + 0xabcdabcd + ? + "PPP" + : + "NULL") +#else /* _SIMULATION_ */ + (U8*)snsm_activate_ind->dti_neighbor +#endif /* _SIMULATION_ */ + ); +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + +#else /*_SNDCP_DTI_2_*/ + if (snsm_activate_ind->dti_direction == SNSM_HOME) { + /* new constant instead of HOME, but the comiler switch! */ + sndcp_set_nsapi_direction(snsm_activate_ind->nsapi, HOME); + } else { + sndcp_set_nsapi_direction(snsm_activate_ind->nsapi, NEIGHBOR); + } + sndcp_set_nsapi_linkid(snsm_activate_ind->nsapi, + snsm_activate_ind->dti_linkid); + sndcp_set_nsapi_neighbor(snsm_activate_ind->nsapi, +#ifdef _SIMULATION_ + (snsm_activate_ind->dti_neighbor == + 0xabcdabcd + ? + "PPP" + : + "NULL") +#else + (U8*)snsm_activate_ind->dti_neighbor +#endif /* _SIMULATION_ */ + ); +#endif /*_SNDCP_DTI_2_*/ +#endif + mg_is_ack(snsm_activate_ind->snsm_qos, &spec, &b); + if (spec) { + if (b) { + /* + * The NSAPI will use acknowledged LLC operation mode. + */ + + BOOL ack = FALSE; + USHORT local_sapi_state = MG_IDLE; + BOOL comp_available = FALSE; + + /* + * Is another compressor available? + */ + #ifdef SNDCP_UPM_INCLUDED + mg_is_comp_available(snsm_activate_ind->sapi, + TRUE, + SNDCP_ACK, + snsm_activate_ind->comp_params.msid, + &comp_available); + #else + mg_is_comp_available(snsm_activate_ind->sapi, + TRUE, + SNDCP_ACK, + snsm_activate_ind->msid, + &comp_available); + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + sndcp_set_nsapi_ack(snsm_activate_ind->nsapi, TRUE); + /* + * Is the affected SAPI already in ack mode or est_pending?? + */ + sndcp_get_sapi_ack(snsm_activate_ind->sapi, &ack); + sndcp_get_sapi_state(snsm_activate_ind->sapi, &local_sapi_state); + + if ((((local_sapi_state & MG_EST) > 0) + || + ((local_sapi_state & MG_XID) > 0)) + && + comp_available) + { + sndcp_set_sapi_state(snsm_activate_ind->sapi, MG_XID_NEC); + mg_set_new_xid_block(snsm_activate_ind); + + } else if (ack) { + + /* check if flow control is received before PDP activation */ + mg_check_unset_nsapi_flow_ctrl_flag (snsm_activate_ind->nsapi,SNDCP_ACK); + /* + * If XID negotiation is not requested, respond + * activation to SM, else send LL_XID_REQ. + */ + #ifdef SNDCP_UPM_INCLUDED + if ((snsm_activate_ind->comp_params.dcomp == NAS_DCOMP_OFF && + snsm_activate_ind->comp_params.hcomp == NAS_HCOMP_OFF) || + ! comp_available) { + #else + if ((snsm_activate_ind->dcomp == SNSM_COMP_NEITHER_DIRECT && + snsm_activate_ind->hcomp == SNSM_COMP_NEITHER_DIRECT) || + ! comp_available) { + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + /* + * If est_pending, the res is sent after est_cnf. + */ + + /* + * Reset service nu to acknowledged LLC mode. + */ + sig_mg_nu_reset_ack(snsm_activate_ind->nsapi, 0, 0, FALSE); + /* + * Open DTI connection. + */ +#ifndef SNDCP_UPM_INCLUDED + mg_dti_open(snsm_activate_ind->nsapi); +#else + nu_ready_ind_if_nec(snsm_activate_ind->nsapi); +#endif + + /* + * + */ + sig_mg_sda_getdata(snsm_activate_ind->sapi, snsm_activate_ind->nsapi); + /* + * Send response + */ + mg_send_snsm_activate_res(snsm_activate_ind->nsapi); + + /* + * unsetting the ACT-state + */ + sndcp_unset_nsapi_state(snsm_activate_ind->nsapi, MG_ACT); + + } else { /* if XID negotiation necessary */ + USHORT punct_sapi_state = MG_IDLE; + + /* + * Increment number of requested compressors. + */ + sndcp_data->vj_count++; + /* + * Set the N-PDU number in the affected nu instance to 0. + */ + sig_mg_nu_reset_ack(snsm_activate_ind->nsapi, 0, 0, TRUE); + /* + * Uplink data transfer on SAPI is completely suspended. + */ + sig_mg_su_suspend(snsm_activate_ind->sapi); + sig_mg_sua_suspend(snsm_activate_ind->sapi); + mg_suspend_affected_nus(snsm_activate_ind->sapi); + /* + * Send prim or store requested compression. + */ + sndcp_get_sapi_state(snsm_activate_ind->sapi, + &punct_sapi_state); + mg_send_xid_req(snsm_activate_ind); + + } /* if XID negotiation necessary */ + } else { + /* + * Is XID negotiation necessary? + */ + #ifdef SNDCP_UPM_INCLUDED + if ((snsm_activate_ind->comp_params.dcomp == NAS_DCOMP_OFF && + snsm_activate_ind->comp_params.hcomp == NAS_HCOMP_OFF) || + sndcp_data->vj_count == SNDCP_MAX_VJ_COUNT) + #else + if ((snsm_activate_ind->dcomp == SNSM_COMP_NEITHER_DIRECT && + snsm_activate_ind->hcomp == SNSM_COMP_NEITHER_DIRECT) || + sndcp_data->vj_count == SNDCP_MAX_VJ_COUNT) + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + { + /* + * Ack mode, sapi not yet established. + * No XID requested. + */ + PALLOC_SDU(ll_establish_req, LL_ESTABLISH_REQ, 0); + + /* + * Reset service nu to acknowledged LLC mode. + */ + sig_mg_nu_reset_ack(snsm_activate_ind->nsapi, 0, 0, TRUE); + + ll_establish_req->sapi = snsm_activate_ind->sapi; + /* + * Set the establishment states of sapi + */ + sndcp_set_sapi_state(snsm_activate_ind->sapi, MG_EST); + /* + * Uplink data transfer on SAPI is completely suspended. + */ + sig_mg_su_suspend(snsm_activate_ind->sapi); + sig_mg_sua_suspend(snsm_activate_ind->sapi); + mg_suspend_affected_nus(snsm_activate_ind->sapi); + + /* + * Send prim to LLC. + */ + sndcp_set_nsapi_rec_state(snsm_activate_ind->nsapi, SDA_ESTABLISH_REQUESTED); + +#ifdef SNDCP_RANGE_CHECK + + if(ll_establish_req EQ NULL) + { + TRACE_EVENT("ERROR: ll_establish_req is NULL"); + } + else if(*((ULONG*)ll_establish_req - 7) NEQ 0) + { + TRACE_EVENT + ("ERROR in SNDCP: ll_establish_req is not allocated"); + } + +#endif /* SNDCP_RANGE_CHECK */ + + PSEND(hCommLLC, ll_establish_req); + } else { + + UBYTE sapi_index = 0; + + /* + * Ack mode, sapi not yet established. + * XID requested. + */ + PALLOC_SDU(ll_establish_req, + LL_ESTABLISH_REQ, + SNDCP_XID_BLOCK_BIT_LEN); + + /* + * Increment number of requested compressors. + */ + sndcp_data->vj_count++; + + sndcp_get_sapi_index(snsm_activate_ind->sapi, &sapi_index); + /* + * Reset service nu to acknowledged LLC mode. + */ + sig_mg_nu_reset_ack(snsm_activate_ind->nsapi, 0, 0, TRUE); + + ll_establish_req->sapi = snsm_activate_ind->sapi; + /* + * Write data from snsm_activate_ind to service variable req_xid_block. + */ + + mg_set_req_xid_block(snsm_activate_ind); + /* + * Fill the XID block. Implementation dependent!!! + */ + mg_set_xid_params(ll_establish_req->sapi, + &ll_establish_req->sdu, + sndcp_data->mg.req_xid_block[sapi_index]); + + /* + * Set the establishment states of sapi + */ + sndcp_set_sapi_state(snsm_activate_ind->sapi, MG_EST); + /* + * Uplink data transfer on SAPI is completely suspended. + */ + sig_mg_su_suspend(snsm_activate_ind->sapi); + sig_mg_sua_suspend(snsm_activate_ind->sapi); + mg_suspend_affected_nus(snsm_activate_ind->sapi); + + /* + * Send prim to LLC. + */ + sndcp_set_nsapi_rec_state(snsm_activate_ind->nsapi, SDA_ESTABLISH_REQUESTED); + +#ifdef SNDCP_RANGE_CHECK + + if(ll_establish_req EQ NULL) + { + TRACE_EVENT("ERROR: ll_establish_req is NULL"); + } + else if(*((ULONG*)ll_establish_req - 7) NEQ 0) + { + TRACE_EVENT + ("ERROR in SNDCP: ll_establish_req is not allocated"); + } + +#endif /* SNDCP_RANGE_CHECK */ + + PSEND(hCommLLC, ll_establish_req); + } + } + } else { + /* + * The NSAPI will not use acknowledged LLC operation mode. + */ + + /* + * Is XID negotiation necessary? + */ + + /* check if flow control is received before PDP activation */ + mg_check_unset_nsapi_flow_ctrl_flag (snsm_activate_ind->nsapi,SNDCP_UNACK); + + +#ifdef TI_PS_FF_V42BIS + #ifdef SNDCP_UPM_INCLUDED + if ((snsm_activate_ind->comp_params.hcomp == NAS_HCOMP_NEITHER_DIRECT + || + sndcp_data->vj_count >= SNDCP_MAX_VJ_COUNT) + && + snsm_activate_ind->comp_params.dcomp == NAS_HCOMP_NEITHER_DIRECT) + #else + if ((snsm_activate_ind->hcomp == SNSM_COMP_NEITHER_DIRECT + || + sndcp_data->vj_count >= SNDCP_MAX_VJ_COUNT) + && + snsm_activate_ind->dcomp == SNSM_COMP_NEITHER_DIRECT) + + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ +#else /* !TI_PS_FF_V42BIS */ + #ifdef SNDCP_UPM_INCLUDED + if (snsm_activate_ind->comp_params.hcomp == NAS_HCOMP_OFF + || + sndcp_data->vj_count == SNDCP_MAX_VJ_COUNT) + #else + if (snsm_activate_ind->hcomp == SNSM_COMP_NEITHER_DIRECT + || + sndcp_data->vj_count == SNDCP_MAX_VJ_COUNT) + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + +#endif /* TI_PS_FF_V42BIS */ + { + + /* + * No XID negotiation necessary. + * BUT LLC needs trigger to send LLC XID request to network. + * If LL_ESTABLISH_REQ or LL_XID_REQ is pending, no LL_XID_REQ + * is needed here. + * If LL_RELEASE_REQ is pending, XID must have been negotiated, + * so it is not necessary. + */ + USHORT local_sapi_state = MG_IDLE; + sndcp_get_sapi_state(snsm_activate_ind->sapi, + &local_sapi_state); + + if (sndcp_data->always_xid + && + (local_sapi_state & MG_EST) == 0 + && + (local_sapi_state & MG_REL) == 0 + && + (local_sapi_state & MG_XID) == 0 + ) { + + /* + * XID negotiation is not necessary, but done for LLC. + */ + /* + * Set the N-PDU number in the affected nu instance to 0. + */ + sig_mg_nu_reset(snsm_activate_ind->nsapi, TRUE); + /* + * Uplink data transfer on SAPI is completely suspended. + */ + sig_mg_su_suspend(snsm_activate_ind->sapi); + sig_mg_sua_suspend(snsm_activate_ind->sapi); + mg_suspend_affected_nus(snsm_activate_ind->sapi); + /* + * Send prim. + */ + mg_send_empty_xid_req(snsm_activate_ind); + + } else { + /* + * No XID negotiation necessary. + */ + + /* + * LLC may send data now + */ + sig_mg_sd_getunitdata(snsm_activate_ind->sapi, snsm_activate_ind->nsapi); + /* + * Open DTI connection. + */ +#ifndef SNDCP_UPM_INCLUDED + mg_dti_open(snsm_activate_ind->nsapi); +#else + nu_unitready_ind_if_nec(snsm_activate_ind->nsapi); +#endif + /* + * Set the N-PDU number in the affected nu instance to 0. + */ + sig_mg_nu_reset(snsm_activate_ind->nsapi, FALSE); + + mg_send_snsm_activate_res(snsm_activate_ind->nsapi); + /* + * The response is now sent, state flag can be unset. + */ + sndcp_unset_nsapi_state(snsm_activate_ind->nsapi, MG_ACT); + + } + + } else { + #ifdef SNDCP_UPM_INCLUDED + if (snsm_activate_ind->comp_params.hcomp > NAS_HCOMP_OFF) { + #else + if (snsm_activate_ind->hcomp > SNSM_COMP_NEITHER_DIRECT) { + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + /* + * Increment number of requested compressors. + */ + sndcp_data->vj_count++; + } + + /* + * XID negotiation is necessary. + */ + /* + * Set the N-PDU number in the affected nu instance to 0. + */ + sndcp_get_sapi_state(snsm_activate_ind->sapi, &sapi_state); + sig_mg_nu_reset(snsm_activate_ind->nsapi, TRUE); + + if (((sapi_state & MG_XID) == 0) + && + ((sapi_state & MG_EST) == 0)) { + + /* + * Uplink data transfer on SAPI is completely suspended. + */ + sig_mg_su_suspend(snsm_activate_ind->sapi); + sig_mg_sua_suspend(snsm_activate_ind->sapi); + mg_suspend_affected_nus(snsm_activate_ind->sapi); + /* + * Send prim. + */ + mg_send_xid_req(snsm_activate_ind); + } else { + mg_set_new_xid_block(snsm_activate_ind); + sndcp_set_sapi_state(snsm_activate_ind->sapi, MG_XID_NEC); + } + + } /* else from if negotiation necessary */ + } /* else from if (b) { */ + } /* if (spec) { */ + if ( sndcp_data->tcp_flow) + { + TRACE_EVENT("sndcp_data.tcp_flow --- DATA FLOW PRIMITIVE "); + TRACE_EVENT_P1("nsapi value %d", snsm_activate_ind->nsapi); + nd_dti_buffer_ready(snsm_activate_ind->nsapi); + } + } /* if (used == FALSE) { */ + break; + default: + TRACE_ERROR( "SNSM_ACTIVATE_IND unexpected" ); + break; + } + if (snsm_activate_ind != NULL) { + PFREE(snsm_activate_ind); + } + +} /* mg_snsm_activate_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : mg_snsm_deactivate_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive SNSM_DEACTIVATE_IND +| +| Parameters : *snsm_deactivate_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +#ifdef SNDCP_UPM_INCLUDED +GLOBAL void mg_snsm_deactivate_ind ( T_SN_DEACTIVATE_REQ *snsm_deactivate_ind ) +#else +GLOBAL void mg_snsm_deactivate_ind ( T_SNSM_DEACTIVATE_IND *snsm_deactivate_ind ) +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ +{ + UBYTE nsapi = 0; + BOOL nec = FALSE; + + TRACE_FUNCTION( "mg_snsm_deactivate_ind" ); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) { +#ifdef SNDCP_UPM_INCLUDED + if (snsm_deactivate_ind->nsapi == nsapi) { +#else + if (snsm_deactivate_ind->nsapi_set & (0x001 << nsapi)) { +#endif + USHORT sapi_state = 0; + BOOL ack = FALSE; + BOOL used = FALSE; + UBYTE sapi = 0; + + /* + * Delete information about requested compressors. + */ + sndcp_reset_xid_block(&sndcp_data->mg.user_xid_block[nsapi]); + /* + * If nsapi is not used, send response anyway to avoid block. + */ + sndcp_is_nsapi_used(nsapi, &used); + if (!used) { +#ifdef SNDCP_UPM_INCLUDED + PALLOC(snsm_deactivate_res, SN_DEACTIVATE_CNF); + snsm_deactivate_res->nsapi = nsapi; + #else + PALLOC(snsm_deactivate_res, SNSM_DEACTIVATE_RES); + snsm_deactivate_res->nsapi = nsapi; + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + /* + * Set the "state" of the nsapi. + */ + sndcp_unset_nsapi_state(nsapi, MG_DEACT); + + +#ifdef SNDCP_UPM_INCLUDED + PSEND(hCommUPM, snsm_deactivate_res); +#else /*#ifdef SNDCP_UPM_INCLUDED*/ + PSEND(hCommSM, snsm_deactivate_res); +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + continue; + } + + + /* + * Close affected DTI connection. + */ +#ifdef _SNDCP_DTI_2_ + /* FIX + for entity test TC TC 321 and TC 327 and TC 262a*/ + sndcp_data->nu = & sndcp_data->nu_base[nsapi]; + /* End FIX */ +#endif /* _SNDCP_DTI_2_ */ +#ifndef SNDCP_UPM_INCLUDED + mg_dti_close(nsapi); +#else + /* + * This part is required for EDGE to get next line out of if + * statement. + */ + {} +#endif + sndcp_set_nsapi_state(nsapi, MG_DEACT); + sndcp_unset_nsapi_state(nsapi, MG_ACT); + + sndcp_get_nsapi_ack(nsapi, &ack); + sndcp_get_nsapi_sapi(nsapi, &sapi); + if (ack) { + mg_rel_nsapi_nec(nsapi); + } + sndcp_get_sapi_state(sapi, &sapi_state); + mg_delete_npdus(nsapi); + sndcp_data->nu_base[nsapi].sn_unitready_ind_pending = FALSE; + sndcp_data->nu_base[nsapi].sn_ready_ind_pending = FALSE; + /* + * is compressor deactivation necessary? + */ + mg_is_rel_comp_nec(nsapi, &nec); + +#ifdef SNDCP_UPM_INCLUDED + if ((snsm_deactivate_ind->rel_ind == PS_REL_IND_YES) + && + ((sapi_state & (MG_REL + MG_REL_NEC_LOC + MG_REL_NEC_PEER)) == 0) + ) { + #else + if ((snsm_deactivate_ind->rel_ind == REL_IND_YES) + && + ((sapi_state & (MG_REL + MG_REL_NEC_LOC + MG_REL_NEC_PEER)) == 0) + ) { + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + /* + * Local deactivation. No LL_XID_REQ will be sent (because rel_ind + * is REL_IND_YES). + * No release is pending or needed. + */ + +#ifdef SNDCP_UPM_INCLUDED + PALLOC(snsm_deactivate_res, SN_DEACTIVATE_CNF); + snsm_deactivate_res->nsapi = nsapi; + #else + PALLOC(snsm_deactivate_res, SNSM_DEACTIVATE_RES); + snsm_deactivate_res->nsapi = nsapi; + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + /* + * Now the NSAPI is not in use anymore: + */ + sndcp_set_nsapi_used(nsapi, FALSE); + sndcp_set_nsapi_ack(nsapi, FALSE); + /* + * Set the "state" of the nsapi. + */ + sndcp_unset_nsapi_state(nsapi, MG_DEACT); + /* + * Reset xid blocks. + */ + mg_reset_compressors(nsapi); + + + #ifdef SNDCP_UPM_INCLUDED + PSEND(hCommUPM, snsm_deactivate_res); + #else + PSEND(hCommSM, snsm_deactivate_res); + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + } else if ((sapi_state & (MG_REL + MG_REL_NEC_LOC + MG_REL_NEC_PEER)) + == 0 + ) { + + /* + * No release is pending. + * If no compressor has to be released: respond to SM. + */ + if (nec) { + /* + * If xid req is sent, suspend uplink transfer for affected sapi. + */ + sig_mg_su_suspend(sapi); + sig_mg_sua_suspend(sapi); + mg_suspend_affected_nus(sapi); + /* + * Negotiate possible deactivation of compressors. + */ + mg_send_xid_req_del(sapi); + + } else { /* if (nec) */ + + sndcp_get_sapi_state(sapi, &sapi_state); + if ((sapi_state & MG_XID_NEC) == 0) { + /* + * No compressor negotiated, no release sent. + */ + + #ifdef SNDCP_UPM_INCLUDED + PALLOC(snsm_deactivate_res, SN_DEACTIVATE_CNF); + snsm_deactivate_res->nsapi = nsapi; + #else + PALLOC(snsm_deactivate_res, SNSM_DEACTIVATE_RES); + snsm_deactivate_res->nsapi = nsapi; + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + + /* + * Now the NSAPI is not in use anymore: + */ + sndcp_set_nsapi_used(nsapi, FALSE); + sndcp_set_nsapi_ack(nsapi, FALSE); + /* + * Set the "state" of the nsapi. + */ + sndcp_unset_nsapi_state(nsapi, MG_DEACT); + + + #ifdef SNDCP_UPM_INCLUDED + PSEND(hCommUPM, snsm_deactivate_res); + #else /*#ifdef SNDCP_UPM_INCLUDED*/ + PSEND(hCommSM, snsm_deactivate_res); + #endif /*#ifdef SNDCP_UPM_INCLUDED*/ + + } + } /* if (nec) */ + } else {/* if ((state & (MG_REL + ....)) == 0) */ + /* + * LL_RELEASE_REQ is pending. After reception of LL_RELEASE_REQ, + * if XID negotiatio is necessary, LL_XID_REQ will be sent. + */ + if (nec) { + sndcp_set_sapi_state(sapi, MG_XID_NEC); + } + } + } + } + break; + default: + TRACE_ERROR( "SNSM_DEACTIVATE_IND unexpected" ); + break; + } + if (snsm_deactivate_ind != NULL) { + PFREE(snsm_deactivate_ind); + } + + +} /* mg_snsm_deactivate_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : mg_snsm_sequence_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive SNSM_SEQUENCE_IND +| +| Parameters : *snsm_sequence_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +#ifdef SNDCP_UPM_INCLUDED +GLOBAL void mg_snsm_sequence_ind ( T_SN_SEQUENCE_REQ *snsm_sequence_ind ) +#else +GLOBAL void mg_snsm_sequence_ind ( T_SNSM_SEQUENCE_IND *snsm_sequence_ind ) +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ +{ + +#ifdef SNDCP_UPM_INCLUDED + int i = 0; + U8 nsapi,rec_no,npdu_number; +#endif + + TRACE_FUNCTION( "mg_snsm_sequence_ind" ); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + { +#ifdef SNDCP_UPM_INCLUDED + + PALLOC(snsm_sequence_res, SN_SEQUENCE_CNF); + + for (i = 0; + i < snsm_sequence_ind->c_receive_no_list; + i++) { + + nsapi = snsm_sequence_ind->receive_no_list[i].nsapi; + rec_no = snsm_sequence_ind->receive_no_list[i].receive_no; + + sndcp_unset_nsapi_state(nsapi, MG_SEQ); + sig_mg_nu_delete_to(nsapi, rec_no); + npdu_number = sig_mg_nd_get_rec_no(nsapi); + snsm_sequence_res->receive_no_list[i].nsapi = nsapi; + snsm_sequence_res->receive_no_list[i].receive_no = npdu_number; + } + snsm_sequence_res->c_receive_no_list = i; + PSEND(hCommUPM, snsm_sequence_res); +#else + TRACE_EVENT_P1( "SEQ_IND rec_no: %d", snsm_sequence_ind->rec_no); + sndcp_unset_nsapi_state(snsm_sequence_ind->nsapi, MG_SEQ); + sig_mg_nu_delete_to(snsm_sequence_ind->nsapi, + snsm_sequence_ind->rec_no); + sig_mg_nd_get_rec_no(snsm_sequence_ind->nsapi); +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ + break; + } + default: + TRACE_ERROR( "SNSM_SEQUENCE_IND unexpected" ); + break; + } + if (snsm_sequence_ind != NULL) { + PFREE (snsm_sequence_ind); + } + +} /* mg_snsm_sequence_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : mg_snsm_modify_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive SNSM_MODIFY_IND +| +| Parameters : *snsm_modify_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +#ifdef SNDCP_UPM_INCLUDED +GLOBAL void mg_snsm_modify_ind ( T_SN_MODIFY_REQ *snsm_modify_ind ) +#else +GLOBAL void mg_snsm_modify_ind ( T_SNSM_MODIFY_IND *snsm_modify_ind ) +#endif /*#ifdef SNDCP_UPM_INCLUDED*/ +{ + /* + * LLC mode specified? + */ + BOOL spec = FALSE; + /* + * LLC mode acknowledged? + */ + BOOL b = FALSE; + BOOL nsapi_used = FALSE; + BOOL old_nsapi_ack = FALSE; + UBYTE old_sapi = 0; + + TRACE_FUNCTION( "mg_snsm_modify_ind" ); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + /* + * If no release/establish will be done, SNSM_MODIFY_RES is expected now. + */ + sndcp_data->mg.mod_expects = MG_MOD_X_READY; + /* + * Is NSAPI already used? + */ + sndcp_is_nsapi_used(snsm_modify_ind->nsapi, &nsapi_used); + if (! nsapi_used) { + mg_mod_nsapi_new(snsm_modify_ind); + } + /* + * Is LLC operation mode changing from unack to ack? + */ + mg_is_ack(snsm_modify_ind->snsm_qos, &spec, &b); + sndcp_get_nsapi_ack(snsm_modify_ind->nsapi, &old_nsapi_ack); + if (spec && b && ! old_nsapi_ack) { + mg_mod_unack_ack(snsm_modify_ind); + } + /* + * Is LLC operation mode changing from ack to unack? + */ + if (spec && ! b && old_nsapi_ack) { + mg_mod_ack_unack(snsm_modify_ind); + } + /* + * Is new sapi different from old one? + */ + sndcp_get_nsapi_sapi(snsm_modify_ind->nsapi, &old_sapi); + if (old_sapi != snsm_modify_ind->sapi) { + mg_mod_sapi_diff(snsm_modify_ind); + } + /* + * Add nsapi to waiting_nsapis + */ + + sndcp_data->mg.waiting_nsapis |= (1 << (snsm_modify_ind->nsapi)); + + /* + * The following will be done in any case: + */ + sndcp_set_nsapi_qos(snsm_modify_ind->nsapi, snsm_modify_ind->snsm_qos); + sndcp_set_nsapi_prio(snsm_modify_ind->nsapi, snsm_modify_ind->radio_prio); + +#ifdef REL99 + sndcp_set_nsapi_pktflowid(snsm_modify_ind->nsapi, + snsm_modify_ind->pkt_flow_id); +#endif /*REL99*/ + /* + * If no establish/release is expected, send res now. + */ + mg_mod_res_if_nec(); + break; + default: + TRACE_ERROR( "SNSM_MODIFY_IND unexpected" ); + break; + } + if (snsm_modify_ind != NULL) { + PFREE(snsm_modify_ind); + } + +} /* mg_snsm_modify_ind() */ + + +#ifndef SNDCP_UPM_INCLUDED +/* ++------------------------------------------------------------------------------ +| Function : mg_sn_switch_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive SN_SWITCH_REQ +| +| Parameters : *snswitch_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL void mg_sn_switch_req ( T_SN_SWITCH_REQ *sn_switch_req ) +{ +#ifdef _SNDCP_DTI_2_ + UBYTE* neighbor = NULL; +#endif /* _SNDCP_DTI_2_ */ + TRACE_FUNCTION( "mg_sn_switch_req" ); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + sndcp_set_nsapi_linkid(sn_switch_req->nsapi, + sn_switch_req->dti_linkid); +#ifdef _SNDCP_DTI_2_ + sndcp_get_nsapi_neighbor(sn_switch_req->nsapi, &neighbor); +#endif /* _SNDCP_DTI_2_ */ +#ifdef _SIMULATION_ + sndcp_set_nsapi_neighbor(sn_switch_req->nsapi, + (sn_switch_req->dti_neighbor == + 0xabcdabcd + ? + "PPP" + : + "NULL")); +#else /*_SIMULATION_ */ + sndcp_set_nsapi_neighbor(sn_switch_req->nsapi, + (UBYTE*)sn_switch_req->dti_neighbor); +#endif /* _SIMULATION_ */ + /* + * Map sn constants to dti constants. + */ + if (sn_switch_req->dti_direction == SN_HOME) { + sndcp_set_nsapi_direction(sn_switch_req->nsapi, HOME); + } else { + sndcp_set_nsapi_direction(sn_switch_req->nsapi, NEIGHBOR); + } +#ifdef _SIMULATION_ +#ifdef _SNDCP_DTI_2_ +/* FIX for entity test TC 1205*/ + sndcp_data->nu = & sndcp_data->nu_base[sn_switch_req->nsapi]; + if ((sndcp_data->nu->connection_is_opened == TRUE) || + ((neighbor != NULL) && !(strcmp(neighbor,"NULL")))) +/* End FIX */ +#endif /* _SNDCP_DTI_2_ */ +#endif /* _SIMULATION_ */ +#ifndef SNDCP_UPM_INCLUDED + mg_dti_close(sn_switch_req->nsapi); +#endif + sndcp_data->nu->sn_switch_cnf_expected = TRUE; +#ifndef SNDCP_UPM_INCLUDED + mg_dti_open(sn_switch_req->nsapi); +#endif + + break; + default: + TRACE_ERROR( "SN_SWITCH_REQ unexpected" ); + break; + } + + PFREE(sn_switch_req); + +} /* mg_sn_switch_req() */ +#endif /*SNDCP_UPM_INCLUDED*/ + + +#ifdef SNDCP_UPM_INCLUDED +/* ++------------------------------------------------------------------------------ +| Function : mg_sn_dti_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive SN_DTI_REQ +| +| Parameters : *sn_dti_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void mg_sn_dti_req ( T_SN_DTI_REQ *sn_dti_req ) +{ + + UBYTE* neighbor = NULL; + + /* + * is nsapi already used? + */ +/* BOOL used = FALSE;*/ + BOOL ack = FALSE; + + TRACE_FUNCTION( "mg_sn_dti_req" ); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + sndcp_set_nsapi_linkid(sn_dti_req->nsapi, + sn_dti_req->dti_linkid); + + TRACE_EVENT_P1("sn_dti_req->nsapi: %d", sn_dti_req->nsapi); + + if (sn_dti_req->dti_conn == NAS_CONNECT_DTI) { + + sndcp_get_nsapi_neighbor(sn_dti_req->nsapi, &neighbor); + sndcp_data->nsapi = sn_dti_req->nsapi; + +#ifdef SNDCP_2to1 + sndcp_set_nsapi_neighbor(sn_dti_req->nsapi, + (U8*)sn_dti_req->dti_neighbor.name); +#else /*SNDCP_2to1*/ +#ifdef _SIMULATION_ + sndcp_set_nsapi_neighbor(sn_dti_req->nsapi, + (sn_dti_req->dti_neighbor == + 0xabcdabcd + ? + "PPP" + : + "NULL")); +#else /*_SIMULATION_ */ + sndcp_set_nsapi_neighbor(sn_dti_req->nsapi, + (U8*)sn_dti_req->dti_neighbor); +#endif /* _SIMULATION_ */ +#endif /*SNDCP_2to1*/ + + /* + * Map sn constants to dti constants. + * The compiler switch is required because the dti_direction + * C-Macros have different values in old and new worlds. + */ + +#ifdef SNDCP_UPM_INCLUDED + if (sn_dti_req->dti_direction == NAS_HOME) + { + sndcp_set_nsapi_direction(sn_dti_req->nsapi, DTI_CHANNEL_TO_LOWER_LAYER); + } + else + { + sndcp_set_nsapi_direction(sn_dti_req->nsapi, DTI_CHANNEL_TO_HIGHER_LAYER); + } +#else /*SNDCP_UPM_INCLUDED*/ + if (sn_dti_req->dti_direction == DTI_CHANNEL_TO_LOWER_LAYER) + { + sndcp_set_nsapi_direction(sn_dti_req->nsapi, DTI_CHANNEL_TO_LOWER_LAYER); + } + else + { + sndcp_set_nsapi_direction(sn_dti_req->nsapi, DTI_CHANNEL_TO_HIGHER_LAYER); + } +#endif + sndcp_set_nsapi_linkid(sn_dti_req->nsapi, + sn_dti_req->dti_linkid); + if (sn_dti_req->dti_neighbor NEQ (ULONG)TCPIP_NAME) + { + mg_dti_open(sn_dti_req->nsapi); + } +#ifdef SNDCP_UPM_INCLUDED + sndcp_get_nsapi_ack(sn_dti_req->nsapi, &ack); + if (ack) { + UBYTE sapi = 0; + USHORT stat = MG_IDLE; + sndcp_get_nsapi_sapi(sn_dti_req->nsapi, &sapi); + sndcp_get_sapi_state(sapi, &stat); + /* + * Do not call nu_ready_ind_if_nec() if establish + * is ongoing. + */ + if ((stat & MG_EST) == 0) { + nu_ready_ind_if_nec(sn_dti_req->nsapi); + } + } else { + nu_unitready_ind_if_nec(sn_dti_req->nsapi); + } +#endif + + } else { /* if (sn_dti_req->dti_conn == SNDCP_CONNECT_DTI) */ + + + /* check if flow control is received before PDP activation */ + mg_check_unset_nsapi_flow_ctrl_flag (sn_dti_req->nsapi,MG_MOD_X_NONE); + + mg_dti_close(sn_dti_req->nsapi); + } /* if (sn_dti_req->dti_conn == SNDCP_CONNECT_DTI) */ + + break; + default: + TRACE_ERROR( "SN_DTI_REQ unexpected" ); + break; + } + + PFREE(sn_dti_req); + +} /* mg_sn_dti_req() */ + + + +#endif /* SNDCP_UPM_INCLUDED */ + +#ifdef TI_DUAL_MODE +/* ++------------------------------------------------------------------------------ +| Function : mg_get_pending_pdu_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive SN_GET_PENDING_PDU_REQ +| +| Parameters : *sn_get_pending_pdu_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void mg_get_pending_pdu_req (T_SN_GET_PENDING_PDU_REQ + *sn_get_pending_pdu_req) +{ + U8 nsapi = 0; + BOOL ack = FALSE, used = FALSE; + + TRACE_FUNCTION( "mg_get_pending_pdu_req" ); + + switch( GET_STATE( MG ) ) + { + case MG_DEFAULT: + { + PALLOC(sn_get_pending_pdu_cnf, SN_GET_PENDING_PDU_CNF); +#ifdef _SIMULATION_ + PALLOC(sn_test_get_pending_pdu_cnf, SN_TEST_GET_PENDING_PDU_CNF); +#endif + memset(sn_get_pending_pdu_cnf->ul_pdus,0, sizeof(T_SN_ul_pdus)); + for (nsapi = 0; nsapi < SN_SIZE_NSAPI; nsapi++) { + sn_get_pending_pdu_cnf->ul_pdus[nsapi].c_desc_list2 = 0; + sn_get_pending_pdu_cnf->ul_pdus[nsapi].nsapi = 0; + sn_get_pending_pdu_cnf->ul_pdus[nsapi].dl_sequence_number = 0; + sndcp_is_nsapi_used(nsapi, &used); + if (used) { + sndcp_get_nsapi_ack(nsapi, &ack); + if (ack) {/*acknowledged context*/ + sn_get_pending_pdu_cnf = + mg_get_unsent_unconfirmed_npdus(nsapi, sn_get_pending_pdu_cnf); + mg_clean_ack_npdu_queues_leave_data(nsapi); + } else {/*unacknowledged context*/ + mg_clean_unack_npdu_queues_including_data(nsapi); + } + } + } + sn_get_pending_pdu_cnf->c_ul_pdus=SN_SIZE_NSAPI; +#ifdef _SIMULATION_ + sm_make_test_pending_pdu_cnf(sn_get_pending_pdu_cnf, + sn_test_get_pending_pdu_cnf); + PSEND(hCommUPM, sn_test_get_pending_pdu_cnf); +#else + PSEND(hCommUPM, sn_get_pending_pdu_cnf); +#endif + break; + } + default: + TRACE_ERROR( "SN_GET_PENDING_PDU_REQ unexpected" ); + break; + } + if (sn_get_pending_pdu_req != NULL) { + PFREE (sn_get_pending_pdu_req); + } +} +#endif /*TI_DUAL_MODE*/