FreeCalypso > hg > fc-magnetite
diff src/g23m-gprs/llc/llc_rxp.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_rxp.c Thu Oct 13 04:24:13 2016 +0000 @@ -0,0 +1,632 @@ +/* ++----------------------------------------------------------------------------- +| 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 primitives as described in +| the SDL-documentation (RX-statemachine) ++----------------------------------------------------------------------------- +*/ + +#ifndef LLC_RXP_C +#define LLC_RXP_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_rxf.h" /* to get local RX functions */ +#include "llc_us.h" /* to get signal interface to U */ +#include "llc_uirxs.h" /* to get signal interface to UIRX */ +#include "llc_irxs.h" /* to get signal interface to IRX */ + +#ifdef _SIMULATION_ +#include <string.h> /* to get memcpy() */ +#endif + +/*==== CONST ================================================================*/ + +/*==== LOCAL VARS ===========================================================*/ + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +#ifdef _SIMULATION_ +LOCAL void rx_copy_test_primitive_data (T_GRLC_UNITDATA_IND_TEST + *grlc_unitdata_ind_test, + T_GRLC_UNITDATA_IND *grlc_unitdata_ind); +#endif + +#ifndef CF_FAST_EXEC + +GLOBAL void rx_grlc_xdata_ind (T_GRLC_UNITDATA_IND *grlc_unitdata_ind); + +#endif /* CF_FAST_EXEC */ + + +/*==== PUBLIC FUNCTIONS =====================================================*/ + + +/* ++------------------------------------------------------------------------------ +| Function : rx_grlc_data_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive GRLC_DATA_IND +| +| Parameters : *grlc_data_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void rx_grlc_data_ind ( T_GRLC_DATA_IND *grlc_data_ind ) +{ + TRACE_FUNCTION( "grlc_data_ind" ); + + switch( GET_STATE( RX ) ) + { + case RX_TLLI_ASSIGNED: + { + /* + * Both primitives are treated the same way and contain the same + * information. + */ + PPASS (grlc_data_ind, grlc_unitdata_ind, GRLC_UNITDATA_IND); + + /* + * Primitive is handled in rx_grlc_xdata_ind(). + */ + rx_grlc_xdata_ind (grlc_unitdata_ind); + break; + } + default: + PFREE_DESC (grlc_data_ind); + TRACE_ERROR( "GRLC_DATA_IND unexpected" ); + break; + } + +} /* rx_grlc_data_ind() */ + +#endif /* CF_FAST_EXEC */ + + +/* ++------------------------------------------------------------------------------ +| Function : rx_grlc_unitdata_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitive GRLC_UNITDATA_IND +| +| Parameters : *grlc_unitdata_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void rx_grlc_unitdata_ind ( T_GRLC_UNITDATA_IND *grlc_unitdata_ind ) +{ + TRACE_FUNCTION( "grlc_unitdata_ind" ); + + switch( GET_STATE( RX ) ) + { + case RX_TLLI_ASSIGNED: + /* + * Primitive is handled in rx_grlc_xdata_ind(). + */ + rx_grlc_xdata_ind (grlc_unitdata_ind); + break; + default: + PFREE_DESC (grlc_unitdata_ind); + TRACE_ERROR( "GRLC_UNITDATA_IND unexpected" ); + break; + } + +} /* rx_grlc_unitdata_ind() */ + +#endif /* CF_FAST_EXEC */ + + +/* ++------------------------------------------------------------------------------ +| Function : rx_cci_decipher_cnf ++------------------------------------------------------------------------------ +| Description : Handles the primitive CCI_DECIPHER_CNF. +| Note: The type LL_UNITDATA_IND is used instead to avoid PPASS +. +| +| Parameters : *ll_unitdata_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +/*#if defined(CF_FAST_EXEC) || defined(_SIMULATION_) || \ + defined(LL_2to1) */ + +GLOBAL void rx_cci_decipher_cnf ( T_LL_UNITDATA_IND *ll_unitdata_ind) +{ + UBYTE cipher; + T_PDU_TYPE frame_type; + T_COMMAND command; + T_BIT cr_bit; + T_BIT pf_bit; + T_FRAME_NUM nr; + T_FRAME_NUM ns; + BOOL frame_ok; + UBYTE frame_rej; + USHORT frame_rej_ctrl_length; + USHORT ctrl_len; + + + TRACE_FUNCTION( "rx_cci_decipher_cnf" ); + + cipher = ll_unitdata_ind->cipher; + + switch( GET_STATE( RX ) ) + { + case RX_TLLI_ASSIGNED: + /* variable sapi is "misused" for fcs_check value */ + if (ll_unitdata_ind->sapi EQ CCI_FCS_PASSED) + { + + { + /* + * Label INTERPRET + */ + + rx_interpret_frame (&ll_unitdata_ind->sdu, &ll_unitdata_ind->sapi, + &frame_type, &command, &cr_bit, &pf_bit, &nr, &ns, &frame_ok, + &frame_rej, &frame_rej_ctrl_length, cipher); + + SWITCH_LLC (ll_unitdata_ind->sapi); + + /* + * In case of I-frames check, if the information field exceeds N201-I + */ + if (frame_type == I_FRAME) + { + ctrl_len = I_CTRL_MIN_OCTETS; + + /* + * Add sizeof SACK-Bitmap, if necessarry (add K+1) + */ + if (command == I_SACK) + { + ctrl_len += (ll_unitdata_ind->sdu.buf[(ll_unitdata_ind->sdu.o_buf/8)+4] + & 0x1F) + 1; + } + + if (BYTELEN(ll_unitdata_ind->sdu.l_buf) > *(llc_data->n201_i) + ctrl_len) + { + frame_ok = FALSE; + frame_rej = FRMR_W2; + + TRACE_0_INFO("Received frame violates N201-I: send FRMR"); + } + } + + /* + * frame_ok includes: correct frame length, PD bit == 0, SAPI valid, + * FCS correct, known PDU type. + */ + if (frame_ok EQ TRUE) + { + rx_strip_llc_header (&ll_unitdata_ind->sdu, frame_type, command); + + /* + * Label S_DATA + */ + + switch (frame_type) + { + case U_FRAME: + /* + * Label U_FRAME + */ + + /* + * Service u_frames receives the SDU within the allocated UNITDATA + * primitive. + */ + sig_rx_u_data_ind (ll_unitdata_ind, command, cr_bit, pf_bit); + break; + case UI_FRAME: + /* + * Label UI_FRAME + */ + + sig_rx_uirx_data_ind (ll_unitdata_ind, nr); + break; + case S_FRAME: + /* + * No break. S frames and I frames are treated the same way. + */ + case I_FRAME: + /* + * Label I_FRAME + */ + + sig_rx_irx_data_ind (ll_unitdata_ind, + command, frame_type, cr_bit, pf_bit, ns, nr); + break; + default: + PFREE (ll_unitdata_ind); + TRACE_ERROR ("unknown frame type"); + break; + } + } + else /* frame_ok EQ FALSE */ + { + /* + * Check if frame rejection condition occurred, and if U has to be + * informed. + */ + if (frame_rej EQ FRAME_NOT_REJ) + { + TRACE_0_INFO("Frame ignored due to decode problem"); + PFREE (ll_unitdata_ind); + } + else /* W1 bit and/or W3 bit set */ + { + /* + * Inform U of the frame rejection condition. + */ + TRACE_0_INFO("Frame rejected due to decode problem"); + sig_rx_u_frmr_ind (ll_unitdata_ind, frame_type, frame_rej_ctrl_length, + cr_bit, frame_rej); + } + } + } /* end of validity range of ll_unitdata_ind */ + } + else /* fcs_check EQ CCI_FCS_FAILED */ + { +#ifdef TRACE_EVE + UBYTE sapi; + + rx_interpret_frame (&ll_unitdata_ind->sdu, &sapi, + &frame_type, &command, &cr_bit, &pf_bit, &nr, &ns, &frame_ok, + &frame_rej, &frame_rej_ctrl_length, cipher); +#endif + TRACE_0_INFO("Frame discarded due to FCS"); + PFREE (ll_unitdata_ind); + } + break; + default: + PFREE(ll_unitdata_ind); + TRACE_ERROR( "CCI_DECIPHER_CNF unexpected" ); + break; + } + +} /* rx_cci_decipher_cnf() */ + +/*#endif */ /* CF_FAST_EXEC || _SIMULATION_ */ + + +/* ++------------------------------------------------------------------------------ +| Function : rx_grlc_data_ind_test ++------------------------------------------------------------------------------ +| Description : Handles the primitive GRLC_DATA_IND_TEST +| NOTE: This is only necessary in simulation environment. +| +| Parameters : *grlc_data_ind_test - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +#ifdef _SIMULATION_ +GLOBAL void rx_grlc_data_ind_test ( T_GRLC_DATA_IND_TEST *grlc_data_ind_test ) +{ + TRACE_FUNCTION( "grlc_data_ind_test" ); + + switch( GET_STATE( RX ) ) + { + case RX_TLLI_ASSIGNED: + { + /* + * Allocate a "normal" GRLC_UNITDATA_IND primitive and copy the data + * of the test primitive GRLC_DATA_IND_TEST (sdu) to + * GRLC_UNITDATA_IND (desc_list). + */ + PALLOC_DESC (grlc_unitdata_ind, GRLC_UNITDATA_IND); + + grlc_unitdata_ind->tlli = grlc_data_ind_test->tlli; + rx_copy_test_primitive_data ((T_GRLC_UNITDATA_IND_TEST *)grlc_data_ind_test, + grlc_unitdata_ind); + + /* + * Free the received test primitive. + */ + PFREE (grlc_data_ind_test); + + /* + * Primitive is handled in rx_grlc_xdata_ind(). + */ + rx_grlc_xdata_ind (grlc_unitdata_ind); + break; + } + default: + PFREE (grlc_data_ind_test); + TRACE_ERROR( "GRLC_DATA_IND_TEST unexpected" ); + break; + } + +} /* rx_grlc_data_ind_test() */ +#endif /* _SIMULATION_ */ + + +/* ++------------------------------------------------------------------------------ +| Function : rx_grlc_unitdata_ind_test ++------------------------------------------------------------------------------ +| Description : Handles the primitive GRLC_UNITDATA_IND_TEST +| NOTE: This is only necessary in simulation environment. +| +| Parameters : *grlc_unitdata_ind_test - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +#ifdef _SIMULATION_ +GLOBAL void rx_grlc_unitdata_ind_test ( T_GRLC_UNITDATA_IND_TEST + *grlc_unitdata_ind_test ) +{ + TRACE_FUNCTION( "grlc_unitdata_ind_test" ); + + switch( GET_STATE( RX ) ) + { + case RX_TLLI_ASSIGNED: + { + /* + * Allocate a "normal" GRLC_UNITDATA_IND primitive and copy the data + * of the test primitive GRLC_UNITDATA_IND_TEST (sdu) to + * GRLC_UNITDATA_IND (desc_list). + */ + PALLOC_DESC (grlc_unitdata_ind, GRLC_UNITDATA_IND); + + grlc_unitdata_ind->tlli = grlc_unitdata_ind_test->tlli; + rx_copy_test_primitive_data (grlc_unitdata_ind_test, grlc_unitdata_ind); + + /* + * Free the received test primitive. + */ + PFREE (grlc_unitdata_ind_test); + + /* + * Primitive is handled in rx_grlc_xdata_ind(). + */ + rx_grlc_xdata_ind (grlc_unitdata_ind); + break; + } + default: + PFREE (grlc_unitdata_ind_test); + TRACE_ERROR( "GRLC_UNITDATA_IND_TEST unexpected" ); + break; + } + +} /* rx_grlc_unitdata_ind_test() */ +#endif /* _SIMULATION_ */ + + +/* ++------------------------------------------------------------------------------ +| Function : rx_copy_test_primitive_data ++------------------------------------------------------------------------------ +| Description : Copies the data of a TEST primitive (sdu) to a normal +| primitive (desc_list). +| ATTENTION: All other parameters of the primitives are left +| untouched and are not copied by this function! +| +| Parameters : *grlc_unitdata_ind_test - source primitive +| *grlc_unitdata_ind - destination primitive +| ++------------------------------------------------------------------------------ +*/ +#ifdef _SIMULATION_ +LOCAL void rx_copy_test_primitive_data (T_GRLC_UNITDATA_IND_TEST + *grlc_unitdata_ind_test, + T_GRLC_UNITDATA_IND *grlc_unitdata_ind) +{ +#define FRAG_LEN 80 /* value + 6 must fit in an pool with lots of entries */ + + T_sdu *sdu; + T_desc *desc; + T_desc *last_desc = NULL; + int sdu_index; + int length; + + + sdu = &grlc_unitdata_ind_test->sdu; + + /* + * Begin at the first relevant octet. + */ + sdu_index = sdu->o_buf/8; + + /* + * Initialise descriptor list length. + */ + grlc_unitdata_ind->desc_list.list_len = 0; + + + /* + * Copy complete SDU to descriptor list using descriptors of max. 10 bytes. + */ + while (sdu_index < sdu->l_buf/8) + { + /* + * Calculate length of descriptor data (= length of remaining sdu buffer + * with a maximum of FRAG_LEN) + */ + length = (sdu_index+FRAG_LEN < sdu->l_buf/8) ? FRAG_LEN + : (sdu->l_buf/8 - sdu_index); + + /* + * Allocate the necessary size for the data descriptor. The size is + * calculated as follows: + * - take the size of a descriptor structure + * - subtract one because of the array buffer[1] to get the size of + * descriptor control information + * - add number of octets of descriptor data + */ + MALLOC (desc, (USHORT)(sizeof(T_desc) - 1 + length)); + + /* + * Fill descriptor control information. + */ + desc->next = (ULONG)NULL; + desc->len = length; + + /* + * Add length of descriptor data to list length. + */ + grlc_unitdata_ind->desc_list.list_len += length; + + /* + * Copy user data from SDU to descriptor. + */ + memcpy (desc->buffer, &sdu->buf[sdu_index], length); + sdu_index += length; + + if (last_desc) + { + /* + * Add this descriptor (not the first) to the descriptor list. + */ + last_desc->next = (ULONG)desc; + } + else + { + /* + * Insert first descriptor in descriptor list. + */ + grlc_unitdata_ind->desc_list.first = (ULONG)desc; + } + + /* + * Store this descriptor for later use. + */ + last_desc = desc; + } + + return; +} /* rx_copy_test_primitive_data */ +#endif /* _SIMULATION_ */ + + +/* ++------------------------------------------------------------------------------ +| Function : rx_grlc_xdata_ind ++------------------------------------------------------------------------------ +| Description : Handles the primitives GRLC_DATA_IND / GRLC_UNITDATA_IND. +| +| Parameters : *grlc_unitdata_ind - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +#ifndef CF_FAST_EXEC + +GLOBAL void rx_grlc_xdata_ind ( T_GRLC_UNITDATA_IND *grlc_unitdata_ind ) +{ + T_PDU_TYPE frame_type; + UBYTE protected_mode; + UBYTE sapi; + T_FRAME_NUM ns; + BOOL ciphering; + USHORT header_size; + BOOL frame_ok; + + + TRACE_FUNCTION( "grlc_xdata_ind" ); + + /* + * Unassigning old TLLI + * + * GMM has to be informed, that new TLLI has been received. So GMM can unassign old TLLI + * and old PTMSI in GRLC + * Old tlli will be unassigned here. Normally GMM has to sent LLGMM_ASSIGN_REQ with + * new_tlli != all 1's and old_tlli == all 1,s. See 04.64 cp. 6.1 <R.LLC.TLLI_ASS.A.002> + */ +#ifdef LL_2to1 + if ( PS_TLLI_INVALID != llc_data->tlli_old +#else + if ( LLGMM_TLLI_INVALID != llc_data->tlli_old +#endif + && grlc_unitdata_ind->tlli != llc_data->tlli_old ) + { + PALLOC ( llgmm_tlli_ind, LLGMM_TLLI_IND ); + llgmm_tlli_ind->new_tlli = grlc_unitdata_ind->tlli; +#ifdef LL_2to1 + llc_data->tlli_old = PS_TLLI_INVALID; +#else + llc_data->tlli_old = LLGMM_TLLI_INVALID; +#endif + PSEND ( hCommGMM, llgmm_tlli_ind); + } + rx_analyse_ctrl_field (grlc_unitdata_ind, &frame_type, &protected_mode, + &sapi, &ns, &ciphering, &header_size, &frame_ok); + + if (frame_ok EQ TRUE) + { + /* + * Check, if the sapi of the frame is supported. If ok, switch context + * and handle the frame. + */ + switch (sapi) + { + case LL_SAPI_1: + case LL_SAPI_3: + case LL_SAPI_5: + case LL_SAPI_7: + case LL_SAPI_9: + case LL_SAPI_11: + SWITCH_LLC (sapi); + rx_send_decipher_req (grlc_unitdata_ind, frame_type, protected_mode, + ns, header_size, ciphering); + /* + * Free only the primitive (desc_list copied in rx_send_decipher_req) + */ + PFREE (grlc_unitdata_ind); /* Do not use PFREE_DESC here !*/ + break; + + default: + /* + * Ignore frame. + * Free prim and desc_list, because they are not used further + */ + PFREE_DESC (grlc_unitdata_ind); + TRACE_0_INFO("Frame received for reserved SAPI"); + break; + } + } + else /* frame_ok NEQ TRUE */ + { + /* + * Free GRLC_UNITDATA_IND along with complete descriptor list. + */ + PFREE_DESC (grlc_unitdata_ind); + TRACE_EVENT("Frame ignored!"); + } + + return; +} /* rx_grlc_xdata_ind() */ + +#endif /* CF_FAST_EXEC */ +