FreeCalypso > hg > fc-tourmaline
diff src/g23m-gprs/llc/llc_txs.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/llc/llc_txs.c Fri Oct 16 06:25:50 2020 +0000 @@ -0,0 +1,937 @@ +/* ++----------------------------------------------------------------------------- +| 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 (TX-statemachine) ++----------------------------------------------------------------------------- +*/ + +#ifndef LLC_TXS_C +#define LLC_TXS_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_f.h" + +#include "llc_txf.h" /* to get local TX functions */ +#include "llc_txl.h" /* to get local TX labels */ +#include "llc_uitxs.h" /* to get signal interface to UITX */ +#include "llc_itxs.h" /* to get signal interface to ITX */ + +#ifdef REL99 +#include "llc_uf.h" /* to get interface to U control frame */ +#endif /* REL99 */ + +/*==== CONST ================================================================*/ + +/*==== LOCAL VARS ===========================================================*/ + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +/*==== PUBLIC FUNCTIONS =====================================================*/ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_tx_assign_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_TX_ASSIGN_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_tx_assign_req (void) +{ + T_SAPI sapi; + + + TRACE_ISIG( "sig_llme_tx_assign_req" ); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_UNASSIGNED_NOT_READY: + SET_STATE (TX, TX_TLLI_ASSIGNED_NOT_READY); + + /* + * ATTENTION: + * The following loops implies that all SAPIs are odd numbers beginning + * with 1! + */ + for (sapi = LL_SAPI_1; sapi <= LL_SAPI_11; sapi += 2) + { + SWITCH_SERVICE (llc, uitx, UIMAP(sapi)); + llc_data->current_sapi = sapi; + + sig_tx_uitx_ready_ind(); + } + + for (sapi = LL_SAPI_3; sapi <= LL_SAPI_11; sapi += 2) + { + SWITCH_SERVICE (llc, itx, IMAP(sapi)); + llc_data->current_sapi = sapi; + + if (sapi != LL_SAPI_7) + { + sig_tx_itx_ready_ind(); + } + } + break; + case TX_TLLI_UNASSIGNED_READY: + SET_STATE (TX, TX_TLLI_ASSIGNED_READY); + + /* + * ATTENTION: + * The following loops implies that all SAPIs are odd numbers beginning + * with 1! + */ + for (sapi = LL_SAPI_1; sapi <= LL_SAPI_11; sapi += 2) + { + SWITCH_SERVICE (llc, uitx, UIMAP(sapi)); + llc_data->current_sapi = sapi; + + sig_tx_uitx_ready_ind(); + } + + for (sapi = LL_SAPI_3; sapi <= LL_SAPI_11; sapi += 2) + { + SWITCH_SERVICE (llc, itx, IMAP(sapi)); + llc_data->current_sapi = sapi; + + if (sapi != LL_SAPI_7) + { + sig_tx_itx_ready_ind(); + } + } + break; + + default: + TRACE_ERROR( "SIG_LLME_TX_ASSIGN_REQ unexpected" ); + break; + } + + return; +} /* sig_llme_tx_assign_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_tx_unassign_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_TX_UNASSIGN_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_tx_unassign_req (void) +{ + TRACE_ISIG( "sig_llme_tx_unassign_req" ); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_ASSIGNED_NOT_READY: + tx_clear_buffer(); + SET_STATE (TX, TX_TLLI_UNASSIGNED_NOT_READY); + break; + + case TX_TLLI_ASSIGNED_READY: + tx_clear_buffer(); + SET_STATE (TX, TX_TLLI_UNASSIGNED_READY); + break; + + default: + TRACE_ERROR( "SIG_LLME_TX_UNASSIGN_REQ unexpected" ); + break; + } + + return; +} /* sig_llme_tx_unassign_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_tx_reset_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_TX_RESET_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_tx_reset_req (void) +{ + TRACE_ISIG( "sig_llme_tx_reset_req" ); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_ASSIGNED_NOT_READY: + /* + * No break! + */ + case TX_TLLI_ASSIGNED_READY: + tx_clear_buffer(); + //sig_tx_uitx_ready_ind(); + break; + + default: + TRACE_ERROR( "SIG_LLME_TX_RESET_REQ unexpected" ); + break; + } + + return; +} /* sig_llme_tx_reset_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_tx_ready_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_TX_READY_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_tx_ready_req (void) +{ + TRACE_ISIG( "sig_llme_tx_ready_req" ); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_ASSIGNED_NOT_READY: + /* + * No break! + */ + case TX_TLLI_ASSIGNED_READY: + sig_tx_uitx_ready_ind(); + break; + + default: + TRACE_ERROR( "SIG_LLME_TX_READY_REQ unexpected" ); + break; + } + + return; +} /* sig_llme_tx_ready_req() */ + + + + +/* ++------------------------------------------------------------------------------ +| Function : sig_u_tx_data_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_U_TX_DATA_REQ +| +| Parameters : ll_unitdata_req - a valid pointer to a GRLC-UNITDATA-REQ +| primitive +| cause - RLC/MAC cause +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_u_tx_data_req +( +#ifdef LL_DESC + T_LL_UNITDESC_REQ *ll_unitdesc_req, +#else + T_LL_UNITDATA_REQ *ll_unitdesc_req, +#endif + UBYTE cause +) +{ + ULONG reservation_no; + BOOL buffer_available; + UBYTE protected_mode; + + TRACE_ISIG( "sig_u_tx_data_req" ); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_ASSIGNED_NOT_READY: + /* No break. */ + case TX_TLLI_ASSIGNED_READY: + + /* + * U frames are always sent with default cause! except cell notification. + */ +#ifdef REL99 + if (cause EQ GRLC_DTACS_CELL_NOTIFI_NULL_FRAME) + { + tx_reserve_buffer (ll_unitdesc_req, PRIM_DATA, cause, + SERVICE_U, &reservation_no, &buffer_available); + } + else +#endif /* REL99 */ + { + tx_reserve_buffer (ll_unitdesc_req, PRIM_DATA, GRLC_DTACS_DEF, + SERVICE_U, &reservation_no, &buffer_available); + } + /* + * U frames are always sent in LLC protected mode. + */ + protected_mode = CCI_PM_PROTECTED; + + { +#ifdef LL_DESC + T_CCI_CIPHER_DESC_REQ *cci_cipher_desc_req; + MALLOC(cci_cipher_desc_req, sizeof(T_CCI_CIPHER_DESC_REQ)); + cci_cipher_desc_req->desc_list3.first = ll_unitdesc_req->desc_list3.first; + cci_cipher_desc_req->desc_list3.list_len = ll_unitdesc_req->desc_list3.list_len; + cci_cipher_desc_req->attached_counter = ll_unitdesc_req->attached_counter; + /* + * decrease attached counter. If no one is still attached + * free the primitive memory + */ + if (ll_unitdesc_req->attached_counter == CCI_NO_ATTACHE) + { + PFREE(ll_unitdesc_req); + } else { + TRACE_0_INFO("LL_UNITDESC_REQ still attached"); + } +#else + PPASS (ll_unitdesc_req, cci_cipher_desc_req, CCI_CIPHER_REQ); +#endif + /* + * Header size (offset of information) is reqired, if ciphering is used + * or if the frame shall be send in unprotected mode. In this case both + * is not true and so it can be ignored. + */ + cci_cipher_desc_req->header_size = 0; + + /* + * Associate reservation_no with the frame. + */ + cci_cipher_desc_req->reference1 = reservation_no; + + /* + * U frames are never sent ciphered, thus define LL_CIPHER_OFF and set + * N(S) to 0 (it is not used). + */ + tx_send_cipher_req (cci_cipher_desc_req, U_FRAME, protected_mode, 0, + LL_CIPHER_OFF, 0); + + } + break; + + default: +#ifdef LL_DESC + llc_cl_desc3_free((T_desc3*)ll_unitdesc_req->desc_list3.first); +#endif /* LL_DESC */ + PFREE (ll_unitdesc_req); + + TRACE_ERROR( "SIG_U_TX_DATA_REQ unexpected" ); + break; + } +} /* sig_u_tx_data_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_uitx_tx_data_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_UITX_TX_DATA_REQ +| +| Parameters : ll_unitdata_req - a valid pointer to a GRLC-UNITDATA-REQ +| primitive +| cipher - indicates if the frame shall be ciphered or not +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_uitx_tx_data_req + ( +#ifdef LL_DESC + T_LL_UNITDESC_REQ *ll_unitdesc_req, +#else + T_LL_UNITDATA_REQ *ll_unitdesc_req, +#endif + UBYTE cipher, + UBYTE cause, + T_FRAME_NUM nu, + ULONG oc + ) + +{ + ULONG reservation_no; + BOOL buffer_available; + UBYTE protected_mode; + + + TRACE_ISIG( "sig_uitx_tx_data_req" ); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_ASSIGNED_NOT_READY: + /* No break. */ + case TX_TLLI_ASSIGNED_READY: + + tx_reserve_buffer (ll_unitdesc_req, PRIM_DATA, cause, SERVICE_UITX, + &reservation_no, &buffer_available); + + if (ll_unitdesc_req->ll_qos.relclass EQ LL_NO_REL) + { + protected_mode = CCI_PM_UNPROTECTED; + } + else /* reliability classes 4 - 1 */ + { + protected_mode = CCI_PM_PROTECTED; + } + + { +#ifdef LL_DESC + T_CCI_CIPHER_DESC_REQ *cci_cipher_desc_req; + MALLOC(cci_cipher_desc_req, sizeof(T_CCI_CIPHER_DESC_REQ)); + cci_cipher_desc_req->desc_list3.first = ll_unitdesc_req->desc_list3.first; + cci_cipher_desc_req->desc_list3.list_len = ll_unitdesc_req->desc_list3.list_len; + cci_cipher_desc_req->attached_counter = ll_unitdesc_req->attached_counter; + /* + * decrease attached counter. If no one is still attached + * free the primitive memory + */ + if (ll_unitdesc_req->attached_counter == CCI_NO_ATTACHE) + { + PFREE(ll_unitdesc_req); + } else { + TRACE_0_INFO("LL_UNITDESC_REQ still attached"); + } +#else + PPASS (ll_unitdesc_req, cci_cipher_desc_req, CCI_CIPHER_REQ); +#endif + /* + * Header size (offset of information) is reqired, if ciphering is used + * or if the frame shall be send in unprotected mode. + */ + cci_cipher_desc_req->header_size = UI_CTRL_MIN_OCTETS; + + /* + * Associate reservation_no with the frame. + */ + cci_cipher_desc_req->reference1 = reservation_no; + + tx_send_cipher_req (cci_cipher_desc_req, UI_FRAME, protected_mode, nu, + cipher, oc); + + if (buffer_available) + { + /* + * Buffer is still available for current SAPI. + */ + sig_tx_uitx_ready_ind(); + } + + } + break; + + default: +#ifdef LL_DESC + llc_cl_desc3_free((T_desc3*)ll_unitdesc_req->desc_list3.first); +#endif /* LL_DESC */ + PFREE (ll_unitdesc_req); + + TRACE_ERROR( "SIG_UITX_TX_DATA_REQ unexpected" ); + break; + } +} /* sig_uitx_tx_data_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_uitx_tx_unitdata_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_UITX_TX_UNITDATA_REQ +| +| Parameters : ll_unitdata_req - a valid pointer to a GRLC-UNITDATA-REQ +| primitive +| cipher - indicates if the frame shall be ciphered or not +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_uitx_tx_unitdata_req +( +#ifdef LL_DESC + T_LL_UNITDESC_REQ *ll_unitdesc_req, +#else + T_LL_UNITDATA_REQ *ll_unitdesc_req, +#endif + UBYTE cipher, + T_FRAME_NUM nu, + ULONG oc +) + +{ + ULONG reservation_no; + BOOL buffer_available; + UBYTE protected_mode; + + + TRACE_ISIG( "sig_uitx_tx_unitdata_req" ); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_ASSIGNED_NOT_READY: + /* No break. */ + case TX_TLLI_ASSIGNED_READY: + + /* + * Parameter cause will be ignored for RLC/MAC unacknowledged frames, + * so set it to 0. + */ + tx_reserve_buffer (ll_unitdesc_req, PRIM_UNITDATA, 0, SERVICE_UITX, + &reservation_no, &buffer_available); + + if (ll_unitdesc_req->ll_qos.relclass EQ LL_NO_REL) + { + protected_mode = CCI_PM_UNPROTECTED; + } + else /* reliability classes 4 - 1 */ + { + protected_mode = CCI_PM_PROTECTED; + } + + { +#ifdef LL_DESC + T_CCI_CIPHER_DESC_REQ *cci_cipher_desc_req; + MALLOC(cci_cipher_desc_req, sizeof(T_CCI_CIPHER_DESC_REQ)); + cci_cipher_desc_req->desc_list3.first = ll_unitdesc_req->desc_list3.first; + cci_cipher_desc_req->desc_list3.list_len = ll_unitdesc_req->desc_list3.list_len; + cci_cipher_desc_req->attached_counter = ll_unitdesc_req->attached_counter; + /* + * decrease attached counter. If no one is still attached + * free the primitive memory + */ + if (ll_unitdesc_req->attached_counter == CCI_NO_ATTACHE) + { + PFREE(ll_unitdesc_req); + } else { + TRACE_0_INFO("LL_UNITDESC_REQ still attached"); + } +#else + PPASS (ll_unitdesc_req, cci_cipher_desc_req, CCI_CIPHER_REQ); +#endif + /* + * Header size (offset of information) is reqired, if ciphering is used + * or if the frame shall be send in unprotected mode. + */ + cci_cipher_desc_req->header_size = UI_CTRL_MIN_OCTETS; + + /* + * Associate reservation_no with the frame. + */ + cci_cipher_desc_req->reference1 = reservation_no; + + tx_send_cipher_req (cci_cipher_desc_req, UI_FRAME, protected_mode, nu, + cipher, oc); + + if (buffer_available) + { + /* + * Buffer is still available for current SAPI. + */ + sig_tx_uitx_ready_ind(); + } + + } + break; + + default: +#ifdef LL_DESC + llc_cl_desc3_free((T_desc3*)ll_unitdesc_req->desc_list3.first); +#endif /* LL_DESC */ + PFREE (ll_unitdesc_req); + + TRACE_ERROR( "SIG_UITX_TX_UNITDATA_REQ unexpected" ); + break; + } +} /* sig_uitx_tx_unitdata_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_itx_tx_data_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_ITX_TX_DATA_REQ +| +| Parameters : ll_data_req - a valid pointer to a GRLC-DATA-REQ primitive +| cause - +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_itx_tx_data_req +( +#ifdef LL_DESC + T_LL_UNITDESC_REQ *ll_unitdesc_req, +#else + T_LL_UNITDATA_REQ *ll_unitdesc_req, +#endif + T_PDU_TYPE frame_type, + T_FRAME_NUM ns, + UBYTE cause, + USHORT header_size, + ULONG oc +) +{ + ULONG reservation_no; + BOOL buffer_available; + UBYTE protected_mode; + + TRACE_ISIG( "sig_itx_tx_data_req" ); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_ASSIGNED_NOT_READY: + /* No break. */ + case TX_TLLI_ASSIGNED_READY: + + tx_reserve_buffer (ll_unitdesc_req, PRIM_DATA, cause, SERVICE_ITX, + &reservation_no, &buffer_available); + + /* + * I/S + S frames always send in protected mode + */ + protected_mode = CCI_PM_PROTECTED; + + { +#ifdef LL_DESC + T_CCI_CIPHER_DESC_REQ *cci_cipher_desc_req; + MALLOC(cci_cipher_desc_req, sizeof(T_CCI_CIPHER_DESC_REQ)); + cci_cipher_desc_req->desc_list3.first = ll_unitdesc_req->desc_list3.first; + cci_cipher_desc_req->desc_list3.list_len = ll_unitdesc_req->desc_list3.list_len; + cci_cipher_desc_req->attached_counter = ll_unitdesc_req->attached_counter; + /* + * free the primitive memory + */ + PFREE(ll_unitdesc_req); +#else + PPASS (ll_unitdesc_req, cci_cipher_desc_req, CCI_CIPHER_REQ); +#endif + /* + * Header size (offset of information) is reqired, if ciphering is used + * or if the frame shall be send in unprotected mode. + */ + cci_cipher_desc_req->header_size = header_size; + + /* + * Associate reservation_no with the frame. + */ + cci_cipher_desc_req->reference1 = reservation_no; + + if (frame_type == S_FRAME) + { + /* + * Do not try to cipher an S frame (there is no information ;-) + */ + tx_send_cipher_req (cci_cipher_desc_req, frame_type, protected_mode, ns, + LL_CIPHER_OFF, oc); + } + else + { + /* + * I frames shall always send ciphered + */ + tx_send_cipher_req (cci_cipher_desc_req, frame_type, protected_mode, ns, + LL_CIPHER_ON, oc); + } + + if (buffer_available) + { + /* + * Buffer is still available for current SAPI. + */ + sig_tx_itx_ready_ind(); + } + + } + break; + + default: + if (ll_unitdesc_req->attached_counter == CCI_NO_ATTACHE) + { +#ifdef LL_DESC + llc_cl_desc3_free((T_desc3*)ll_unitdesc_req->desc_list3.first); +#endif /* LL_DESC */ + PFREE (ll_unitdesc_req); + } + TRACE_ERROR( "SIG_ITX_TX_DATA_REQ unexpected" ); + break; + } +} /* sig_itx_tx_data_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_tx_trigger_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_TX_TRIGGER_REQ +| +| Parameters : cause - trigger cause +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_tx_trigger_req (UBYTE cause) +{ + T_TX_QUEUE *elem; + + + TRACE_ISIG( "sig_llme_tx_trigger_req" ); + + TRACE_1_PARA("cause:%d", cause); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_ASSIGNED_NOT_READY: + /* no break! */ + case TX_TLLI_ASSIGNED_READY: + tx_get_first_data_frame (&elem); + + if (elem EQ NULL) + { +#ifdef REL99 + if (cause EQ LLGMM_TRICS_CELL_UPDATE_NULL_FRAME) + { + cause = GRLC_DTACS_CELL_NOTIFI_NULL_FRAME; + sig_tx_u_send_null(cause); + } + else +#endif /* REL99 */ + if (cause EQ LLGMM_TRICS_CELL_UPDATE) + { + cause = GRLC_DTACS_EMPTY_FRAME; + sig_tx_uitx_trigger_ind (cause); + } + else + { + sig_tx_uitx_trigger_ind (cause); + } + } + else /* elem is valid */ + { + /* + * NOTE: Possible cause values are DEFAULT, MOBILITY_MANAGEMENT, + * PAGE_RESPONSE, CELL_UPDATE and CELL NOTIFICATION. + * Overwriting DEFAULT, MOBILITY_MANAGEMENT, and the same cause + * (which is already set) is ok. This leaves two relevant (and + * mutually exclusive) trigger causes to be considered. A problem may + * occur if the primitive contained the one remaining trigger cause + * and the other is requested. But according to ANS this should not + * happen. + */ + + if ((cause EQ LLGMM_TRICS_CELL_UPDATE) +#ifdef REL99 + OR + (cause EQ LLGMM_TRICS_CELL_UPDATE_NULL_FRAME) +#endif /*REL99*/ + ) + { + cause = GRLC_DTACS_DEF; + } + + if (elem->primitive EQ NULL) + { + /* + * Primitive is not yet ready-to-send. Modify cause in primitve + * header variable. + */ + elem->ph_cause = cause; + } + else /* elem->primitive is valid */ + { + /* + * Primitive is ready-to-send. Modifiy cause in primitive. + */ + ((T_GRLC_DATA_REQ *)(elem->primitive))->cause = cause; + } + } + break; + + default: + TRACE_ERROR( "SIG_LLME_TX_TRIGGER_REQ unexpected" ); + break; + } +} /* sig_llme_tx_trigger_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_tx_suspend_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_TX_SUSPEND_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_tx_suspend_req (void) +{ + TRACE_ISIG( "sig_llme_tx_suspend_req" ); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_UNASSIGNED_NOT_READY: + case TX_TLLI_ASSIGNED_NOT_READY: + /* + * Nothing to do + */ + break; + + case TX_TLLI_ASSIGNED_READY: + /* + * Flow Control has to be re-started by GRLC + */ + SET_STATE (TX, TX_TLLI_ASSIGNED_NOT_READY); + break; + + case TX_TLLI_UNASSIGNED_READY: + /* + * Flow Control has to be re-started by GRLC + */ + SET_STATE (TX, TX_TLLI_UNASSIGNED_NOT_READY); + break; + + default: + TRACE_ERROR( "SIG_LLME_TX_SUSPEND_REQ unexpected" ); + break; + } +} /* sig_llme_tx_suspend_req() */ + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_tx_resume_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_TX_RESUME_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_tx_resume_req (BOOL grlc_was_suspened) +{ + T_GRLC_DATA_REQ *grlc_data_req; + T_GRLC_UNITDATA_REQ *grlc_unitdata_req; + T_PRIM_TYPE prim_type; + T_SERVICE rx_service; + UBYTE sapi; + + TRACE_ISIG( "sig_llme_tx_resume_req" ); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_UNASSIGNED_NOT_READY: + case TX_TLLI_ASSIGNED_NOT_READY: + /* + * Nothing to do + */ + break; + + case TX_TLLI_ASSIGNED_READY: + if (grlc_was_suspened == FALSE) + { + /* + * LLME indicates that any data may now be sent again. + */ + do { + tx_get_next_frame (&grlc_data_req, &grlc_unitdata_req, &prim_type, + &rx_service, &sapi); + + switch (prim_type) + { + case PRIM_DATA: + /* + * Label S_DATA + */ + tx_label_s_data (rx_service, grlc_data_req); + break; + case PRIM_UNITDATA: + /* + * Label S_UNITDATA + */ + tx_label_s_unitdata (rx_service, grlc_unitdata_req); + break; + case PRIM_REMOVED: + /* + * Label S_REMOVED + */ + tx_label_s_removed (rx_service, sapi); + break; + default: /* NO_PRIM */ + break; + } + } while (prim_type == PRIM_REMOVED); + } + else + { + /* + * Flow Control has to be re-started by GRLC + */ + SET_STATE (TX, TX_TLLI_ASSIGNED_NOT_READY); + } + break; + + case TX_TLLI_UNASSIGNED_READY: + /* + * Flow Control has to be re-started by GRLC + */ + SET_STATE (TX, TX_TLLI_UNASSIGNED_NOT_READY); + break; + + default: + TRACE_ERROR( "SIG_LLME_TX_RESUME_REQ unexpected" ); + break; + } +} /* sig_llme_tx_resume_req() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : sig_llme_tx_flush_req ++------------------------------------------------------------------------------ +| Description : Handles the internal signal SIG_LLME_TX_FLUSH_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void sig_llme_tx_flush_req (T_SERVICE service) +{ + TRACE_ISIG( "sig_llme_tx_flush_req" ); + + switch( GET_STATE( TX ) ) + { + case TX_TLLI_ASSIGNED_READY: + case TX_TLLI_ASSIGNED_NOT_READY: + tx_remove_data_frames (service, llc_data->current_sapi); + break; + + default: + TRACE_ERROR( "SIG_LLME_TX_FLUSH_REQ unexpected" ); + break; + } +} /* sig_llme_tx_flush_req() */ +