FreeCalypso > hg > fc-magnetite
diff src/g23m-gprs/sndcp/sndcp_sdas.c @ 183:219afcfc6250
src/g23m-gprs: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 13 Oct 2016 04:24:13 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-gprs/sndcp/sndcp_sdas.c Thu Oct 13 04:24:13 2016 +0000 @@ -0,0 +1,596 @@ +/* ++----------------------------------------------------------------------------- +| Project : GPRS (8441) +| Modul : sndcp_sdas.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 process internal signals as +| described in the SDL-documentation (SD-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" +#include "sndcp.h" /* to get the global entity definitions */ +#include "sndcp_f.h" /* to get the functions to access the global arrays*/ + +#include "sndcp_sdaf.h" /* to get the internal functions of this service */ +#include "sndcp_nds.h" /* to get signals to nd service */ + + +/*==== CONST ================================================================*/ + +/*==== LOCAL VARS ===========================================================*/ + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +/*==== PUBLIC FUNCTIONS =====================================================*/ + +/* ++------------------------------------------------------------------------------ +| Function : sig_cia_sda_cia_decomp_ind ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_CIA_SDA_CIA_DECOMP_IND +| +| Parameters : cia_decomp_ind, p_id +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_cia_sda_cia_decomp_ind (T_CIA_DECOMP_IND* cia_decomp_ind, UBYTE p_id) +{ + UBYTE sapi_index = 0; + UBYTE sapi = 0; + UBYTE nsapi= cia_decomp_ind->pdu_ref.ref_nsapi; + BOOL rec = FALSE; + T_SN_DATA_IND* sn_data_ind = NULL; + + TRACE_ISIG( "sig_cia_sda_cia_decomp_ind" ); + + /* + * set service instance according to sapi in primitive + */ + sndcp_get_nsapi_sapi(cia_decomp_ind->pdu_ref.ref_nsapi, &sapi); + sndcp_get_sapi_index(sapi, &sapi_index); + sndcp_data->sda = & sndcp_data->sda_base[sapi_index]; + + + switch( sndcp_get_nsapi_rec_state(nsapi) ) + { + case SDA_RECEIVE_FIRST_SEGMENT: + case SDA_RECEIVE_SUBSEQUENT_SEGMENT: + case SDA_ESTABLISH_REQUESTED: + { + + MALLOC(sn_data_ind, sizeof(T_SN_DATA_IND)); + +#ifdef _SNDCP_DTI_2_ + sn_data_ind->desc_list2.first = cia_decomp_ind->desc_list2.first; + sn_data_ind->desc_list2.list_len = cia_decomp_ind->desc_list2.list_len; +#endif /*_SNDCP_DTI_2_*/ + +#ifdef SNDCP_TRACE_ALL + + sndcp_data->cia.cia_decomp_ind_number[nsapi] --; + TRACE_EVENT_P1("number of cia_decomp_ind: % d", + sndcp_data->cia.cia_decomp_ind_number[nsapi]); +#endif /* SNDCP_TRACE_ALL */ + + sn_data_ind->nsapi = nsapi; + sn_data_ind->p_id = p_id; + sda_is_nsapi_rec(nsapi, &rec); + if (rec) { + sda_set_nsapi_rec(nsapi, FALSE); + sig_sda_nd_data_ind(nsapi, + sn_data_ind, + (UBYTE)cia_decomp_ind->pdu_ref.ref_npdu_num); + sda_get_data_if_nec(sapi); + } else { + if (sndcp_data->sda->cur_sn_data_ind[nsapi] NEQ NULL) + { +#ifndef NTRACE +#ifdef SNDCP_TRACE_ALL + TRACE_EVENT_P1("Discard cur_sn.. in %s", sndcp_data->sda->state_name); +#endif /* SNDCP_TRACE_ALL */ +#endif /* NTRACE */ + sda_delete_cur_sn_data_ind(nsapi); + } + sndcp_data->sda->cur_sn_data_ind[nsapi] = sn_data_ind; + sndcp_data->sda->uncomp_npdu_num = + (UBYTE)cia_decomp_ind->pdu_ref.ref_npdu_num; + sndcp_set_nsapi_rec_state(nsapi, SDA_WAIT_NSAPI); + sda_get_data_if_nec ( sapi ); + } + } + MFREE(cia_decomp_ind); + break; + default: + TRACE_ERROR( "SIG_CIA_SDA_CIA_DECOMP_IND unexpected" ); + MFREE_PRIM(cia_decomp_ind); + break; + } +} /* sig_cia_sda_cia_decomp_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : sig_mg_sda_delete_npdus ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_MG_SD_DELETE_NPDUS +| +| Parameters : affected NSAPI, SAPI +| Pre : If the affected SAPI no longer uses acknowledged LLC operation +| mode, no LL_GETDATA_REQ shall be sent. So sndcp_sapi_state_ra +| must already be set to MG_REL_PENDING before this functon is +| called (if that sub state is desired). +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_mg_sda_delete_npdus (UBYTE nsapi, + UBYTE sapi) +{ + UBYTE sapi_index = 0; + + TRACE_ISIG( "sig_mg_sda_delete_npdus" ); + + /* + * set service instance according to sapi in primitive + */ + sndcp_get_sapi_index(sapi, &sapi_index); + sndcp_data->sda = & sndcp_data->sda_base[sapi_index]; + + switch( sndcp_get_nsapi_rec_state(nsapi) ) + { + case SDA_ESTABLISH_REQUESTED: + case SDA_RECEIVE_FIRST_SEGMENT: + case SDA_RECEIVE_SUBSEQUENT_SEGMENT: + if (sndcp_data->sda->cur_sn_data_ind[nsapi] != NULL) { + sda_delete_cur_sn_data_ind(nsapi); + sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT); + } else { + sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT); + } + break; + case SDA_WAIT_NSAPI: + if (sndcp_data->sda->cur_sn_data_ind[nsapi] != NULL) { + USHORT sapi_state = MG_IDLE; + + sda_delete_cur_sn_data_ind(nsapi); + /* + * Does it make sense to request another acknowlegded segment or is + * the whole SAPI now using only unacknowledged mode? + */ + sndcp_get_sapi_state(sapi, &sapi_state); + if ((sapi_state & MG_REL) == 0) { + sda_get_data_if_nec(sapi); + } + sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT); + } + break; + default: + TRACE_ERROR( "SIG_MG_SDA_DELETE_NPDUS unexpected" ); + break; + } +} /* sig_mg_sda_delete_npdus() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_mg_sda_end_est ++------------------------------------------------------------------------------ +| Description : Handles the signal PD_SD_END_EST +| +| Parameters : affected sapi, success +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_mg_sda_end_est (UBYTE sapi, BOOL success) +{ + UBYTE sapi_index = 0; + UBYTE nsapi = 0; + + TRACE_FUNCTION( "sig_pda_sda_est_cnf" ); + + /* + * set service instance according to sapi in primitive + */ + sndcp_get_sapi_index(sapi, &sapi_index); + sndcp_data->sda = & sndcp_data->sda_base[sapi_index]; + + /* + * Send LL_GETDATA_REQ. + */ + if (success){ + sndcp_data->sda->llc_may_send = FALSE; + sda_get_data_if_nec(sapi); + } + /* + * All nsapis at this sapi that use ack mode, enter + * SDA_ESTABLISH_REQUESTED state. + */ + for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) { + UBYTE local_sapi = 0; + BOOL used = FALSE; + + sndcp_is_nsapi_used(nsapi, &used); + if (!used) { + continue; + } + sndcp_get_nsapi_sapi(nsapi, &local_sapi); + if (local_sapi == sapi) { + switch( sndcp_get_nsapi_rec_state(nsapi) ) + { + case SDA_ESTABLISH_REQUESTED: + case SDA_RECEIVE_FIRST_SEGMENT: + case SDA_RECEIVE_SUBSEQUENT_SEGMENT: + case SDA_WAIT_NSAPI: + case SDA_ACK_DISCARD: + sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT); + break; + default: + TRACE_EVENT( "SIG_MG_SDA_END_EST unexpected for this NSAPI" ); + break; + } + } + } /* for all nsapis */ + + +} /* sig_mg_sda_end_est() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_mg_sda_getdata ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_MG_SD_GETDATA +| +| Parameters : sapi +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_mg_sda_getdata (UBYTE sapi, UBYTE nsapi) +{ + UBYTE sapi_index = 0; + + TRACE_ISIG( "sig_mg_sda_getdata" ); + + /* + * set service instance according to sapi in primitive + */ + sndcp_get_sapi_index(sapi, &sapi_index); + sndcp_data->sda = & sndcp_data->sda_base[sapi_index]; + + switch( GET_STATE(SDA) ) + { + case SDA_DEFAULT: + sda_get_data_if_nec(sapi); + sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT); + break; + default: + TRACE_ERROR( "SIG_MG_SDA_GETDATA unexpected" ); + break; + } +} /* sig_mg_sda_getdata() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_cia_sda_getdata ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_CIA_SDA_GETDATA +| +| Parameters : sapi +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_cia_sda_getdata (UBYTE sapi, UBYTE nsapi) +{ + + TRACE_ISIG( "sig_cia_sda_getdata" ); + + switch( sndcp_get_nsapi_rec_state(nsapi) ) + { + case SDA_RECEIVE_FIRST_SEGMENT: + case SDA_RECEIVE_SUBSEQUENT_SEGMENT: + case SDA_WAIT_NSAPI: + sda_get_data_if_nec(sapi); + break; + default: + TRACE_ERROR( "SIG_CIA_SDA_GETDATA unexpected" ); + break; + } +} /* sig_cia_sda_getdata() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_nd_sda_getdata_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_ND_SDA_GETDATA_REQ +| +| Parameters : affected sapi, affected nsapi +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_nd_sda_getdata_req (UBYTE sapi, + UBYTE nsapi) +{ + UBYTE sapi_index = 0; + + TRACE_ISIG( "sig_nd_sda_getdata_req" ); + + /* + * set service instance according to sapi in primitive + */ + sndcp_get_sapi_index(sapi, &sapi_index); + sndcp_data->sda = & sndcp_data->sda_base[sapi_index]; + + switch( sndcp_get_nsapi_rec_state(nsapi) ) + { + case SDA_RECEIVE_FIRST_SEGMENT: + case SDA_RECEIVE_SUBSEQUENT_SEGMENT: + sda_set_nsapi_rec(nsapi, TRUE); + break; + case SDA_WAIT_NSAPI: + if (sndcp_data->sda->cur_sn_data_ind[nsapi] != NULL) { + /* + * Send the just reassembled N-PDU (must be present because of state!). + */ + sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT); + sig_sda_nd_data_ind(nsapi, + sndcp_data->sda->cur_sn_data_ind[nsapi], + sndcp_data->sda->uncomp_npdu_num); + sndcp_data->sda->cur_sn_data_ind[nsapi] = NULL; + sda_get_data_if_nec(sapi); + } else { + /* + * Set the receptive for the given nsapi. + */ + sda_set_nsapi_rec(nsapi, TRUE); + } + break; + default: + TRACE_ERROR( "SIG_ND_SDA_GETDATA_REQ unexpected" ); + break; + } +} /* sig_nd_sda_getdata_req() */ + +/* ++------------------------------------------------------------------------------ +| Function : sig_mg_sda_start_est ++------------------------------------------------------------------------------ +| Description : Handles the signal PD_SD_START_EST +| +| Parameters : affected sapi +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_mg_sda_start_est (UBYTE sapi) +{ + UBYTE nsapi = 0; + + TRACE_FUNCTION( "sig_pda_sda_start_est" ); + + /* + * All nsapis at this sapi that use ack mode, enter + * SDA_ESTABLISH_REQUESTED state. + */ + for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) { + UBYTE sapi_help = 0; + BOOL used = FALSE; + + sndcp_is_nsapi_used(nsapi, &used); + if (!used) { + continue; + } + sndcp_get_nsapi_sapi(nsapi, &sapi_help); + if (sapi_help == sapi) { + switch( sndcp_get_nsapi_rec_state(nsapi) ) + { + case SDA_ESTABLISH_REQUESTED: + case SDA_RECEIVE_FIRST_SEGMENT: + case SDA_RECEIVE_SUBSEQUENT_SEGMENT: + case SDA_WAIT_NSAPI: + sndcp_set_nsapi_rec_state(nsapi, SDA_ESTABLISH_REQUESTED); + break; + default: + TRACE_EVENT( "SIG_MG_SDA_START_EST unexpected for this NSAPI" ); + break; + } + } + } /* for all nsapis */ + +} /* sig_mg_sda_start_est() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_pd_sda_data_ind ++------------------------------------------------------------------------------ +| Description : Handles the signal PD_SD_DATA_IND +| +| Parameters : *ll_data_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_pda_sda_data_ind ( T_LL_DATA_IND *ll_data_ind ) +{ + UBYTE sapi_index = 0; + BOOL valid = FALSE; + UBYTE nsapi = 0; + UBYTE sapi = 0; + + TRACE_FUNCTION( "sig_pda_sda_data_ind" ); + + /* + * set service instance according to sapi in primitive + */ + sndcp_get_sapi_index(ll_data_ind->sapi, &sapi_index); + sndcp_data->sda = & sndcp_data->sda_base[sapi_index]; + sda_get_nsapi(ll_data_ind, &nsapi); + + /* + * LLC has now "used up" it's pending LL_GETDATA_REQ and will have + * to wait for the next one. + */ + sndcp_data->sda->llc_may_send = FALSE; + sapi = ll_data_ind->sapi; + + switch( sndcp_get_nsapi_rec_state(nsapi) ) + { + case SDA_ESTABLISH_REQUESTED: + /* + * Just discard the segment. Next segment will be requested after + * confirmation of establishment. + */ + PFREE(ll_data_ind); + ll_data_ind = NULL; + break; + + case SDA_RECEIVE_FIRST_SEGMENT: + /* + * Invalid segments are discarded without error notification + */ + sda_is_seg_valid(ll_data_ind, &valid); + if (!valid) { + PFREE(ll_data_ind); + sda_get_data_if_nec(sapi); + return; + } + if (sda_f_bit(ll_data_ind)) { + if (sda_m_bit(ll_data_ind)) { + sda_ac_f_f1_m1(ll_data_ind); + } else { + sda_ac_f_f1_m0(ll_data_ind); + } + } else { + sda_ac_f_f0(ll_data_ind); + } + + break; + + case SDA_RECEIVE_SUBSEQUENT_SEGMENT: + /* + * Invalid segments are discarded without error notification + */ + sda_is_seg_valid(ll_data_ind, &valid); + if (!valid) { + PFREE(ll_data_ind); + sda_get_data_if_nec(sapi); + return; + } + if (sda_f_bit(ll_data_ind)) { + if (sda_m_bit(ll_data_ind)) { + sda_ac_s_f1_m1(ll_data_ind); + } else { + sda_ac_s_f1_m0(ll_data_ind); + } + } else { + if (sda_m_bit(ll_data_ind)) { + sda_ac_s_f0_m1(ll_data_ind); + } else { + sda_ac_s_f0_m0(ll_data_ind); + } + } + + break; + + case SDA_WAIT_NSAPI: + if (ll_data_ind != NULL) + { + PFREE(ll_data_ind); + } + sda_get_data_if_nec(sapi); + break; + + case SDA_ACK_DISCARD: + /* + * In this state we will discard every downlink segment till we receive. + * the last segment. + * Once we receive the last segment, we will move to the state + * SDA_RECEIVE_FIRST_SEGMENT. + */ + TRACE_EVENT( "SDA_ACK_DISCARD state,Discard Segments ..." ); + sndcp_data->cur_segment_number[nsapi] ++; + if (!sda_m_bit(ll_data_ind)) + { + TRACE_EVENT( "Received the last Segment in SDA_ACK_DISCARD state " ); + sndcp_data->cur_segment_number[nsapi] = 0; + sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT); + } + PFREE(ll_data_ind); + sda_get_data_if_nec(sapi); + break; + + default: + TRACE_ERROR( "SIG_PDA_SDA_DATA_IND unexpected" ); + /* + * The primitive LL_DATA_IND is unexpected or the + * NSAPI value is wrong. Discard the prim and send a FC prim. + */ + if (ll_data_ind != NULL) + { + PFREE(ll_data_ind); + } + sda_get_data_if_nec(sapi); + break; + } + +} /* sig_pda_sda_data_ind() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_mg_sda_reset_ind ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_MG_SDA_RESET_IND +| +| Parameters : affected sapi +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_mg_sda_reset_ind (UBYTE nsapi) +{ + + TRACE_ISIG( "sig_mg_sda_reset_ind" ); + + switch( sndcp_get_nsapi_rec_state(nsapi) ) + { + case SDA_ESTABLISH_REQUESTED: + case SDA_RECEIVE_FIRST_SEGMENT: + case SDA_RECEIVE_SUBSEQUENT_SEGMENT: + case SDA_WAIT_NSAPI: + case SDA_ACK_DISCARD: + /* + * Similar to sd. + */ + sndcp_data->cur_dcomp[nsapi] = 0; + sndcp_data->cur_pcomp[nsapi] = 0; + break; + default: + TRACE_ERROR( "SIG_MG_SDA_RESET_IND unexpected" ); + break; + } +} /* sig_mg_sda_reset_ind() */ +