FreeCalypso > hg > fc-magnetite
diff src/g23m-gprs/llc/llc_itxs.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/llc/llc_itxs.c Thu Oct 13 04:24:13 2016 +0000 @@ -0,0 +1,742 @@ +/* ++----------------------------------------------------------------------------- +| Project : +| Modul : ++----------------------------------------------------------------------------- +| 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 LLC and implements all +| functions to handles the incoming process internal signals as +| described in the SDL-documentation (ITX-statemachine) ++----------------------------------------------------------------------------- +*/ + +#ifndef LLC_ITXS_C +#define LLC_ITXS_C +#endif + +#define ENTITY_LLC + +/*==== INCLUDES =============================================================*/ + +#include "typedefs.h" /* to get Condat data types */ +#include "vsi.h" /* to get a lot of macros */ +#include "macdef.h" +#include "gprs.h" +#include "gsm.h" /* to get a lot of macros */ +#include "cnf_llc.h" /* to get cnf-definitions */ +#include "mon_llc.h" /* to get mon-definitions */ +#include "prim.h" /* to get the definitions of used SAP and directions */ +#include "llc.h" /* to get the global entity definitions */ + +#include "llc_itxs.h" /* to get ITX signal definitions */ +#include "llc_itxf.h" /* to get ITX function definitions */ +#include "llc_itxt.h" /* to get ITX T201 function definitions */ + +/*==== CONST ================================================================*/ + +/*==== LOCAL VARS ===========================================================*/ + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +/*==== PUBLIC FUNCTIONS =====================================================*/ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_itx_assign_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_ITX_ASSIGN_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_itx_assign_req (void) +{ + TRACE_ISIG( "sig_llme_itx_assign_req" ); + + switch (GET_STATE(ITX)) + { + case ITX_TLLI_UNASSIGNED: + /* + * Init Sapi + */ + itx_init_sapi(); + SET_STATE (ITX, ITX_TLLI_ASSIGNED); + break; + + default: + TRACE_ERROR( "SIG_LLME_ITX_ASSIGN_REQ unexpected" ); + break; + } +} /* sig_llme_itx_assign_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_itx_unassign_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_ITX_UNASSIGN_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_itx_unassign_req (void) +{ + TRACE_ISIG( "sig_llme_itx_unassign_req" ); + + switch (GET_STATE(ITX)) + { + case ITX_TLLI_UNASSIGNED: + /* + * Ignore unexpected signal. + */ + break; + + default: + TIMERSTOP (T201); + itx_s_queue_clean (); + itx_i_queue_clean (); + itx_init_sapi (); + SET_STATE (ITX, ITX_TLLI_UNASSIGNED); + break; + } +} /* sig_llme_itx_unassign_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_itx_reset_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_ITX_RESET_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_itx_reset_req (void) +{ + TRACE_ISIG( "sig_llme_itx_reset_req" ); + + switch (GET_STATE(ITX)) + { + case ITX_TLLI_UNASSIGNED: + case ITX_TLLI_ASSIGNED: + /* + * nothing to do + */ + break; + + case ITX_ABM: + case ITX_ABM_PEER_BUSY: + TIMERSTOP (T201); + itx_s_queue_clean (); + itx_i_queue_clean (); + itx_init_sapi (); + SET_STATE (ITX, ITX_TLLI_ASSIGNED); + break; + + default: + TRACE_ERROR( "SIG_LLME_ITX_RESET_REQ unexpected" ); + break; + } +} /* sig_llme_itx_reset_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_itx_abmest_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_ITX_ABMEST_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_itx_abmest_req (void) +{ + TRACE_ISIG( "sig_llme_itx_abmest_req" ); + + switch (GET_STATE(ITX)) + { + case ITX_TLLI_UNASSIGNED: + /* + * Ignore unexpected signal. + */ + TRACE_ERROR( "SIG_LLME_ITX_ABMEST_REQ unexpected" ); + break; + + default: + TIMERSTOP (T201); + itx_s_queue_clean (); + itx_i_queue_clean (); + itx_init_sapi (); + itx_handle_ll_ready_ind (FALSE); + SET_STATE (ITX, ITX_ABM); + TRACE_1_INFO("ABM established s:%d", llc_data->current_sapi); + break; + } +} /* sig_llme_itx_abmest_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_itx_abmrel_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_ITX_ABMREL_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_itx_abmrel_req (void) +{ + TRACE_ISIG( "sig_llme_itx_abmrel_req" ); + + switch (GET_STATE(ITX)) + { + case ITX_TLLI_UNASSIGNED: + /* + * Ignore unexpected signal. + */ + TRACE_ERROR( "SIG_LLME_ITX_ABMREL_REQ unexpected" ); + break; + + default: + TIMERSTOP (T201); + itx_s_queue_clean (); + itx_i_queue_clean (); + itx_init_sapi (); + SET_STATE (ITX, ITX_TLLI_ASSIGNED); + TRACE_1_INFO("ABM released s:%d", llc_data->current_sapi); + break; + } +} /* sig_llme_itx_abmrel_req() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_itx_suspend_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_ITX_SUSPEND_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_itx_suspend_req (void) +{ + TRACE_ISIG( "sig_llme_itx_suspend_req" ); + + switch (GET_STATE(ITX)) + { + case ITX_TLLI_UNASSIGNED: + case ITX_TLLI_ASSIGNED: + /* + * nothing to do + */ + break; + + case ITX_ABM: + case ITX_ABM_PEER_BUSY: + /* + * Reset T201, but do NOT reset t201_entry pointer + * because we have to restart T201 later! + */ + TIMERSTOP (T201); + /* SET_STATE (ITX, SAME_STATE); */ + break; + + default: + TRACE_ERROR( "SIG_LLME_ITX_SUSPEND_REQ unexpected" ); + break; + } +} /* sig_llme_itx_suspend_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_itx_resume_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_ITX_RESUME_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_itx_resume_req (void) +{ + TRACE_ISIG( "sig_llme_itx_resume_req" ); + + switch (GET_STATE(ITX)) + { + case ITX_TLLI_UNASSIGNED: + case ITX_TLLI_ASSIGNED: + /* + * nothing to do + */ + break; + + case ITX_ABM: + /* + * Restart T201 if a frame was associated to it. + * Do not increment frame retransmission counter. + */ + if ( llc_data->itx->t201_entry != NULL ) + { + TIMERSTART (T201, llc_data->t200->length); + } + + /* + * Continue sending of frames + */ + itx_send_next_frame (ABIT_NO_REQ); + break; + + case ITX_ABM_PEER_BUSY: + /* + * Restart T201, but do not increment counter + */ + TIMERSTART (T201, llc_data->t200->length); + break; + + default: + TRACE_ERROR( "SIG_LLME_ITX_RESUME_REQ unexpected" ); + break; + } +} /* sig_llme_itx_resume_req() */ + + + + +/* ++------------------------------------------------------------------------------ +| Function : sig_tx_itx_ready_ind ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_TX_ITX_READY_IND +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_tx_itx_ready_ind (void) +{ + TRACE_ISIG( "sig_tx_itx_ready_ind" ); + + switch (GET_STATE(ITX)) + { + case ITX_TLLI_ASSIGNED: + llc_data->itx->tx_waiting = TRUE; + /* SET_STATE (ITX, SAME_STATE); */ + break; + + case ITX_ABM: + case ITX_ABM_PEER_BUSY: + llc_data->itx->tx_waiting = TRUE; + itx_send_next_frame (ABIT_NO_REQ); + /* SET_STATE (ITX, SAME_STATE); */ + break; + + default: + TRACE_ERROR( "SIG_TX_ITX_READY_IND unexpected" ); + break; + } +} /* sig_tx_itx_ready_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : sig_irx_itx_ack_ind ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_IRX_ITX_ACK_IND +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_irx_itx_ack_ind (BOOL is_ack, T_FRAME_NUM num) +{ + TRACE_ISIG( "sig_irx_itx_ack_ind" ); + + num %= (MAX_SEQUENCE_NUMBER+1); + +#ifdef TRACE_EVE + { + if (is_ack == TRUE) + { + TRACE_1_INFO("got frame ack:%d", num); + } + else + { + TRACE_1_INFO("got frame request:%d", num); + } + } +#endif + + switch (GET_STATE(ITX)) + { + case ITX_ABM: + case ITX_ABM_PEER_BUSY: + /* + * Set frame acknowledge status in the ITX queue. + */ + if (is_ack) + itx_i_queue_set_status (IQ_IS_ACK_FRAME, num); + else + itx_i_queue_set_status (IQ_RETR_FRAME, num); + + /* SET_STATE (ITX, SAME_STATE); */ + break; + + default: + TRACE_ERROR( "SIG_IRX_ITX_ACK_IND unexpected" ); + break; + } +} /* sig_irx_itx_ack_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : sig_irx_itx_cnf_l3data_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_IRX_ITX_CNF_L3DATA_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_irx_itx_cnf_l3data_req (void) +{ + UBYTE state; + BOOL found; + BOOL data_retrieved = FALSE; +#ifdef LL_2to1 + T_LL_reference1 reference; +#else + T_reference1 reference; +#endif + + TRACE_ISIG( "sig_irx_itx_cnf_l3data_req" ); + + state = GET_STATE(ITX); + + switch (state) + { + case ITX_ABM: + case ITX_ABM_PEER_BUSY: + /* + * Get all acknowledged frames from the ITX queue. + * If one or more are found, send an LL_DATA_CNF + * for each group of max LL_MAX_CNF L3-PDUs. + */ + itx_i_queue_get_ready (&found, &reference, state); + data_retrieved = found; + + /* + * Label LLC_ACK_IND + */ + + while (found) + { + int num_ref = 0; + + PALLOC (ll_data_cnf, LL_DATA_CNF); + + ll_data_cnf->sapi = llc_data->current_sapi; + + do { + + ll_data_cnf->reference1[num_ref] = reference; + num_ref++; + + itx_i_queue_get_ready (&found, &reference, state); + + } while (found && (num_ref < LLC_MAX_CNF)); + + ll_data_cnf->c_reference1 = num_ref; + + TRACE_1_OUT_PARA("s:%d", ll_data_cnf->sapi ); + PSEND (hCommSNDCP, ll_data_cnf); + } + + /* + * If we have taken data from queue, check + * if a L3 ready indication is required + */ + if (data_retrieved) + { + itx_handle_ll_ready_ind (data_retrieved); + } + + /* SET_STATE (ITX, SAME_STATE); */ + break; + + default: + TRACE_ERROR( "SIG_IRX_ITX_CNF_L3DATA_REQ unexpected" ); + break; + } +} /* sig_irx_itx_cnf_l3data_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_irx_itx_trigger_ind ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_IRX_ITX_TRIGGER_IND +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_irx_itx_trigger_ind (void) +{ + TRACE_ISIG( "sig_irx_itx_trigger_ind" ); + + switch (GET_STATE(ITX)) + { + case ITX_ABM: + case ITX_ABM_PEER_BUSY: + itx_send_next_frame (ABIT_NO_REQ); + /* SET_STATE (ITX, SAME_STATE); */ + break; + + default: + TRACE_ERROR( "SIG_IRX_ITX_TRIGGER_IND unexpected" ); + break; + } +} /* sig_irx_itx_trigger_ind() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_irx_itx_peer_busy_ind ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_IRX_ITX_PEER_BUSY_IND +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_irx_itx_peer_busy_ind (void) +{ + TRACE_ISIG( "sig_irx_itx_peer_busy_ind" ); + + switch (GET_STATE(ITX)) + { + case ITX_ABM: + /* + * Start T201 to supervise peer busy condition, + * init T201 peer busy restart counter and change + * into peer busy state. + */ + TIMERSTART (T201, llc_data->t200->length); + llc_data->itx->n_pb_retr = 0; + SET_STATE (ITX, ITX_ABM_PEER_BUSY); + TRACE_1_INFO("Peer Busy s:%d", llc_data->current_sapi); + break; + + case ITX_ABM_PEER_BUSY: + /* + * Restart T201 to supervise peer busy condition, + * reset T201 peer busy restart counter. + */ + TIMERSTART (T201, llc_data->t200->length); + llc_data->itx->n_pb_retr = 0; + break; + + default: + TRACE_ERROR( "SIG_IRX_ITX_PEER_BUSY_IND unexpected" ); + break; + } +} /* sig_irx_itx_peer_busy_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : sig_irx_itx_peer_ready_ind ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_IRX_ITX_PEER_READY_IND +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_irx_itx_peer_ready_ind (void) +{ + TRACE_ISIG( "sig_irx_itx_peer_ready_ind" ); + + switch (GET_STATE(ITX)) + { + case ITX_ABM: + /* + * ignore it + */ + break; + + case ITX_ABM_PEER_BUSY: + /* + * Clear peer busy condition + */ + SET_STATE (ITX, ITX_ABM); + + /* + * Restart T201 if a frame was associated to it. + * Do not increment frame retransmission counter. + */ + if ( llc_data->itx->t201_entry != NULL ) + { + TIMERSTART (T201, llc_data->t200->length); + } + + /* + * Restart sending of frames + */ + TRACE_1_INFO("Peer Ready s:%d", llc_data->current_sapi); + itx_send_next_frame (ABIT_NO_REQ); + break; + + default: + TRACE_ERROR( "SIG_IRX_ITX_PEER_READY_IND unexpected" ); + break; + } +} /* sig_irx_itx_peer_ready_ind() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : sig_irx_itx_send_rr_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_IRX_ITX_SEND_RR_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_irx_itx_send_rr_req (T_ABIT_REQ_TYPE req_type) +{ + TRACE_ISIG( "sig_irx_itx_send_rr_req" ); + + switch (GET_STATE(ITX)) + { + case ITX_ABM: + case ITX_ABM_PEER_BUSY: + itx_s_queue_store (I_RR, req_type, llc_data->sapi->vr, NULL); + itx_send_next_frame (ABIT_NO_REQ); + /* SET_STATE (ITX, SAME_STATE); */ + break; + + default: + TRACE_ERROR( "SIG_IRX_ITX_SEND_RR_REQ unexpected" ); + break; + } +} /* sig_irx_itx_send_rr_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_irx_itx_send_ack_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_IRX_ITX_SEND_ACK_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_irx_itx_send_ack_req (T_ABIT_REQ_TYPE req_type) +{ + TRACE_ISIG( "sig_irx_itx_send_ack_req" ); + + switch (GET_STATE(ITX)) + { + case ITX_ABM: + case ITX_ABM_PEER_BUSY: + itx_s_queue_store (I_ACK, req_type, llc_data->sapi->vr, NULL); + itx_send_next_frame (ABIT_NO_REQ); + /* SET_STATE (ITX, SAME_STATE); */ + break; + + default: + TRACE_ERROR( "SIG_IRX_ITX_SEND_ACK_REQ unexpected" ); + break; + } +} /* sig_irx_itx_send_ack_req() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : sig_irx_itx_send_sack_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_IRX_ITX_SEND_SACK_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_irx_itx_send_sack_req (T_ABIT_REQ_TYPE req_type, T_SACK_BITMAP* bitmap) +{ + TRACE_ISIG( "sig_irx_itx_send_sack_req" ); + + switch (GET_STATE(ITX)) + { + case ITX_ABM: + case ITX_ABM_PEER_BUSY: + itx_s_queue_store (I_SACK, req_type, llc_data->sapi->vr, bitmap); + itx_send_next_frame (ABIT_NO_REQ); + /* SET_STATE (ITX, SAME_STATE); */ + break; + + default: + TRACE_ERROR( "SIG_IRX_ITX_SEND_SACK_REQ unexpected" ); + break; + } +} /* sig_irx_itx_send_sack_req() */ + + + + +/* ++------------------------------------------------------------------------------ +| Function : sig_irx_itx_send_rnr_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_IRX_ITX_SEND_RNR_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_irx_itx_send_rnr_req (T_ABIT_REQ_TYPE req_type) +{ + TRACE_ISIG( "sig_irx_itx_send_rnr_req" ); + + switch (GET_STATE(ITX)) + { + case ITX_ABM: + case ITX_ABM_PEER_BUSY: + itx_s_queue_store (I_RNR, req_type, llc_data->sapi->vr, NULL); + itx_send_next_frame (ABIT_NO_REQ); + /* SET_STATE (ITX, SAME_STATE); */ + break; + + default: + TRACE_ERROR( "SIG_IRX_ITX_SEND_RNR_REQ unexpected" ); + break; + } +} /* sig_irx_itx_send_rnr_req() */ +