FreeCalypso > hg > fc-magnetite
diff src/g23m-gprs/grlc/grlc_tmp.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/grlc/grlc_tmp.c Thu Oct 13 04:24:13 2016 +0000 @@ -0,0 +1,1758 @@ +/* ++----------------------------------------------------------------------------- +| Project : GPRS (8441) +| Modul : GRLC ++----------------------------------------------------------------------------- +| 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 module implements primitive handler functions for service +| TM of entity GRLC. ++----------------------------------------------------------------------------- +*/ + +#ifndef GRLC_TMP_C +#define GRLC_TMP_C +#endif + +#define ENTITY_GRLC + +/*==== INCLUDES =============================================================*/ + +#include "typedefs.h" /* to get Condat data types */ +#include "vsi.h" /* to get a lot of macros */ +#include <string.h> +#include "macdef.h" +#include "gprs.h" +#include "gsm.h" /* to get a lot of macros */ +#include "ccdapi.h" /* to get CCD API */ +#include "cnf_grlc.h" /* to get cnf-definitions */ +#include "mon_grlc.h" /* to get mon-definitions */ +#include "prim.h" /* to get the definitions of used SAP and directions */ +#include "message.h" /* to get air message definitions */ +#include "grlc.h" /* to get the global entity definitions */ +#include "grlc_f.h" /* to get the grlc global function definitions */ +#include "grlc_rus.h" /* to get the service RU signal definitions */ +#include "grlc_rds.h" /* to get the service RD signal definitions */ +#include "grlc_tmf.h" /* to get the service TM functions definitions */ +#include "grlc_meass.h" /* to get the service MEAS signal definitions */ +#include "grlc_tpcs.h" +#if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH +#include "grlc_tms.h" +#endif + +/*==== CONST ================================================================*/ + +/*==== DIAGNOSTICS ==========================================================*/ + +/*==== LOCAL VARS ===========================================================*/ + +/*==== LOCAL TYPES ==========================================================*/ + +LOCAL void tm_uplink_data_req ( T_PRIM_TYPE prim_type, + void *llc_data_req ); + +/*==== PRIVATE FUNCTIONS ====================================================*/ +/* ++------------------------------------------------------------------------------ +| Function : tm_uplink_data_req ++------------------------------------------------------------------------------ +| Description : Handles the primitives GRLC_DATA_REQ and GRLC_UNITDATA_REQ +| +| Parameters : *llc_data_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +LOCAL void tm_uplink_data_req ( T_PRIM_TYPE prim_type, + void *llc_data_req ) +{ + UBYTE state = GET_STATE( TM ); + BOOL use_data_req; + + T_GRLC_DATA_REQ *grlc_data_req = ( T_GRLC_DATA_REQ* )llc_data_req; + T_GRLC_UNITDATA_REQ *grlc_unitdata_req = ( T_GRLC_UNITDATA_REQ* )llc_data_req; + + TRACE_FUNCTION( "tm_uplink_data_req" ); + + PACCESS( llc_data_req ); + +#ifdef FLOW_TRACE + + sndcp_trace_flow_control + ( FLOW_TRACE_GRLC, FLOW_TRACE_UP, FLOW_TRACE_TOP, FALSE ); + +#endif + + if( + ( + grlc_test_mode_active( ) + ) + AND + ( + ( prim_type EQ CGRLC_LLC_PRIM_TYPE_DATA_REQ AND + grlc_data_req->sapi NEQ GRLC_SAPI_TEST_MODE ) + OR + ( prim_type EQ CGRLC_LLC_PRIM_TYPE_UNITDATA_REQ AND + grlc_unitdata_req->sapi NEQ GRLC_SAPI_TEST_MODE ) + ) + ) + { + /* + * all LLC data requests are ignored during GPRS test mode + */ + TRACE_EVENT( "tm_uplink_data_req: GPRS test mode active" ); + PFREE( llc_data_req ); + + return; + } + + + if( prim_type EQ CGRLC_LLC_PRIM_TYPE_DATA_REQ AND + grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE AND + ( grlc_data_req->cause EQ GRLC_DTACS_EMPTY_FRAME OR + grlc_data_req->cause EQ GRLC_DTACS_CELL_NOTIFI_NULL_FRAME ) ) + { + TRACE_EVENT_P1("EMPTY FRAME RECEIVED, LLLC FRAME AVAILABLE, delete empty frame: sdu_len=%d", grlc_data_req->sdu.l_buf / 8); + grlc_data->tm.send_grlc_ready_ind = SEND_A_GRLC_READY_IND; + tm_handle_grlc_ready_ind( ); + PFREE( llc_data_req ); + return; + } + + + +/* + + if( prim_type EQ PRIM_TYPE_DATA_REQ ) + { + TRACE_EVENT_P2( "tm_uplink_data_req: sdu_len=%ld data_req_cnt=%d", + grlc_data_req->sdu.l_buf / 8, + grlc_data->grlc_data_req_cnt ); + + TRACE_EVENT_P9( "tm_uplink_data_req: sapi=%d tlli=%lx delay=%d relc=%d peak=%d prec=%d mean=%d r_pri=%d cause=%d", + grlc_data_req->sapi, + grlc_data_req->tlli, + grlc_data_req->qos.delay, + grlc_data_req->qos.relclass, + grlc_data_req->qos.peak, + grlc_data_req->qos.preced, + grlc_data_req->qos.mean, + grlc_data_req->radio_prio, + grlc_data_req->cause ); + } + +*/ + + grlc_data->tm.send_grlc_ready_ind = SEND_A_GRLC_READY_IND; + + switch( state ) + { + case TM_ACCESS_DISABLED: + case TM_ACCESS_PREPARED: + use_data_req = + ( + grlc_data->tm.disable_class EQ CGRLC_DISABLE_CLASS_CR + ) + AND + ( + ( prim_type EQ CGRLC_LLC_PRIM_TYPE_DATA_REQ AND + grlc_data_req->cause EQ GRLC_DTACS_DEF ) + OR + ( prim_type EQ CGRLC_LLC_PRIM_TYPE_UNITDATA_REQ ) + ); + break; + + default: + use_data_req = tm_access_allowed ( grlc_data_req->radio_prio ); + break; + } + + if( use_data_req ) + { + tm_data_req( prim_type, ( T_GRLC_DATA_REQ* )llc_data_req ); + grlc_data->grlc_data_req_cnt++; + + switch( state ) + { + case TM_PIM: + tm_ul_tbf_ind(); + break; + + case TM_PTM: + tm_ul_tbf_ind(); + + if( grlc_data->tbf_type NEQ TBF_TYPE_DL ) + { + /* uplink is active*/ + sig_tm_ru_queue_status( ); + } + break; + + default: + /* do nothing */ + break; + } + } + else + { + tm_cgrlc_status_ind( CGRLC_ACCESS_2_NETWORK_NOT_ALLOWED ); + PFREE( llc_data_req ); + } + + tm_handle_grlc_ready_ind( ); + +} /* tm_uplink_data_req () */ + +/*==== PUBLIC FUNCTIONS =====================================================*/ +/* ++------------------------------------------------------------------------------ +| Function : tm_grlc_data_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive GRLC_DATA_REQ +| +| Parameters : *grlc_data_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_grlc_data_req ( T_GRLC_DATA_REQ *grlc_data_req ) +{ + TRACE_FUNCTION( "tm_grlc_data_req " ); + + tm_uplink_data_req( CGRLC_LLC_PRIM_TYPE_DATA_REQ, ( void* )grlc_data_req ); + +} /* tm_grlc_data_req () */ + +/* ++------------------------------------------------------------------------------ +| Function : tm_grlc_unitdata_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive GRLC_UNITDATA_REQ +| +| Parameters : *grlc_unitdata_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_grlc_unitdata_req ( T_GRLC_UNITDATA_REQ *grlc_unitdata_req ) +{ + TRACE_FUNCTION( "tm_grlc_unitdata_req" ); + + tm_uplink_data_req( CGRLC_LLC_PRIM_TYPE_UNITDATA_REQ, ( void* )grlc_unitdata_req ); + +} /* tm_grlc_unitdata_req() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : tm_t3168 ++------------------------------------------------------------------------------ +| Description : Handles the primitive T3168 +| This timer is involved in 3 Procedures +| 1) Two Phase Access Procedure +| 2) Uplink TBF Setup on existing Downlink TBF +| 3) Uplink Realloaction Procedure on existing Uplink TBF +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_t3168 ( void ) +{ + TRACE_FUNCTION( "tm_t3168" ); + TRACE_EVENT_P1("T3168 expired: n_acc=%d",grlc_data->tm.n_res_req); + + /* + * The expiry of this timer may occure in 3 cases: + * + * a) uplink allocation during running downlink TBF --> GRLC + * b) two phase access procedure --> GRLC + * c) uplink reallocation procedure on uplink TBF or on concurent TBF(UL&DL) -->GRLC + * + */ + + switch( GET_STATE( TM ) ) + { + case TM_PTM: + switch(grlc_data->tbf_type) + { +#if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH + case TBF_TYPE_TP_ACCESS: + grlc_data->uplink_tbf.ti=1; + tm_handle_error_ra(); + break; +#endif + case TBF_TYPE_DL: + /* + * cse a) + */ + if(grlc_data->tm.n_res_req < 4) /* Is resource re-allocation is running? */ + { + grlc_data->tm.n_res_req++; + tm_build_chan_req_des(&grlc_data->chan_req_des, + &grlc_data->prim_queue[grlc_data->prim_start_tbf]); + sig_tm_rd_ul_req(); + } + else + { /* grlc_data->tm.n_res_req EQ 4 + -> last Channel Request Description has been sent */ + tm_handle_error_ra(); + } + break; + + case TBF_TYPE_UL: + case TBF_TYPE_CONC: + /* + * case c) + */ + if(grlc_data->tm.n_res_req < 4) /* Is resource re-allocation is running? */ + { + T_U_GRLC_RESOURCE_REQ resource_req;/*lint !e813*/ + + tm_build_res_req(&resource_req, + R_RE_ALLOC); + tm_store_ctrl_blk( CGRLC_BLK_OWNER_TM, ( void* )&resource_req ); + } + else + { /* + * grlc_data->tm.n_res_req EQ 4 -> last resource request has been sent + * return to packet idle and indicate packet access failure to upper layers + */ + while(grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL) + { + grlc_delete_prim(); + } + tm_cgrlc_status_ind(CGRLC_PACKET_ACCESS_FAILURE); + tm_abort_tbf(grlc_data->tbf_type); + grlc_data->tm.n_res_req = 0; + TRACE_EVENT("4x p. resource req. failed"); + SET_STATE(TM,TM_WAIT_4_PIM); + } + break; + default: + /* + * Should never occure + */ + TRACE_ERROR("T3168 expired, no task should not appear"); + break; + } + + break; + + default: + TRACE_ERROR( "T3168 unexpected" ); + break; + } + +} /* tm_t3168() */ + + +/* ++------------------------------------------------------------------------------ +| Function : tm_t3188 ++------------------------------------------------------------------------------ +| Description : Handles the primitive T3188 +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_t3188 ( void ) +{ + TRACE_FUNCTION( "tm_t3188" ); + + + switch( GET_STATE( TM ) ) + { + case TM_PTM: + /* + * perform abnormal release with random access + */ + tm_handle_error_ra(); + break; + default: + TRACE_ERROR( "tm_t3188 unexpected" ); + break; + } + +} /* tm_t3188() */ + + +/* ++------------------------------------------------------------------------------ +| Function : tm_grlc_activate_gmm_queue_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive GRLC_ACTIVATE_GMM_QUEUE_REQ +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_grlc_activate_gmm_queue_req ( T_GRLC_ACTIVATE_GMM_QUEUE_REQ *grlc_activate_gmm_queue_req ) +{ + TRACE_FUNCTION( "tm_grlc_activate_gmm_queue_req" ); + + + switch( GET_STATE( TM ) ) + { + case TM_ACCESS_DISABLED: + tm_get_gmm_prim_queue( ); + break; + + case TM_ACCESS_PREPARED: + SET_STATE( TM, TM_PIM ); + sig_tm_ru_reset_poll_array(); + tm_get_gmm_prim_queue( ); + tm_handle_grlc_ready_ind( ); + break; + + default: + TRACE_ERROR( "GRLC_ACTIVATE_GMM_QUEUE_REQ unexpected" ); + break; + } + + PFREE( grlc_activate_gmm_queue_req ); + +} /* tm_grlc_activate_gmm_queue_req() */ + +/* ++------------------------------------------------------------------------------ +| Function : tm_grlc_flush_data_req ++------------------------------------------------------------------------------ +| Description : When LLC receives XID RESET during Inter-SGSN RAU procedure, +| LLC sends this primitive GRLC_FLUSH_DATA_REQ to GRLC to flush out LLC +| user data maintained in GRLC +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL void tm_grlc_flush_data_req (T_GRLC_FLUSH_DATA_REQ *grlc_flush_data_req) +{ + + UBYTE i; + UBYTE temp_start_tbf; + UBYTE temp_start_free; + + TRACE_FUNCTION( "tm_grlc_flush_data_req" ); + + TRACE_EVENT_P4(" ps=%d, pf=%d,sps=%d,spf=%d", + grlc_data->prim_start_tbf, + grlc_data->prim_start_free, + grlc_data->save_prim_start_tbf, + grlc_data->save_prim_start_free); + + + if(!grlc_data->gmm_procedure_is_running OR + !(grlc_data->prim_start_tbf >= PRIM_QUEUE_SIZE)) + /* Check for the condition grlc_data->prim_start_tbf EQ 0xFF is not required since + * grlc_data->prim_start_tbf=0xFF implies there are no primitives in queue to flush out. + * LLC PDUs are flushed only when GMM queue is active dring Inter-SGSN RAU procedure */ + { + TRACE_ERROR( "GRLC_FLUSH_DATA_REQ unexpected" ); + PFREE(grlc_flush_data_req); + return; + } + + /* Remember GMM primitives when gmm procedure is running*/ + temp_start_tbf = grlc_data->prim_start_tbf; + temp_start_free = grlc_data->prim_start_free; + + /* Retrieve the saved primitive values when LLC was suspended by GMM */ + grlc_data->prim_start_tbf = grlc_data->save_prim_start_tbf; + grlc_data->prim_start_free = grlc_data->save_prim_start_free; + + i = grlc_data->prim_start_tbf; + + grlc_data->prim_user_data = 0; + while(i NEQ 0xFF) + { + grlc_data->prim_user_data += BYTELEN(grlc_data->prim_queue[i].prim_ptr->sdu.l_buf); + i = grlc_data->prim_queue[i].next; + } + grlc_data->tm.send_grlc_ready_ind = SEND_A_GRLC_READY_IND; + + /* Delete all LLC primitives (user data) irrespective of going in same or new tbf */ + + do + { + grlc_delete_prim(); + } while( (grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL)); + + + grlc_data->save_prim_start_tbf = grlc_data->prim_start_tbf; + if(grlc_data->prim_start_tbf NEQ 0xff) + { + TRACE_ASSERT(grlc_data->prim_start_tbf NEQ 0xff); + } + + tm_handle_grlc_ready_ind(); + + /* The GMM primitive values are put back */ + grlc_data->prim_start_tbf = temp_start_tbf; + grlc_data->prim_start_free = temp_start_free; + + + TRACE_EVENT_P4(" ps=%d, pf=%d,sps=%d,spf=%d", + grlc_data->prim_start_tbf, + grlc_data->prim_start_free, + grlc_data->save_prim_start_tbf, + grlc_data->save_prim_start_free); + + + PFREE(grlc_flush_data_req); + +} + + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_enable_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive cgrlc_enable_req +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_enable_req ( T_CGRLC_ENABLE_REQ *cgrlc_enable_req ) +{ + TRACE_FUNCTION( "tm_cgrlc_enable_req" ); + + + switch( GET_STATE( TM ) ) + { + case TM_ACCESS_DISABLED: + case TM_ACCESS_PREPARED: + if( cgrlc_enable_req->enable_cause EQ + CGRLC_ENAC_ABNORM_RELEASE_CRESELECT_FAILED ) + { + SET_STATE( TM, TM_PIM ); + sig_tm_ru_reset_poll_array(); + tm_cgrlc_status_ind( CGRLC_RLC_MAC_ERROR ); + tm_delete_prim_queue( ); + } + else if(cgrlc_enable_req->queue_mode EQ CGRLC_QUEUE_MODE_GMM) + { + if(grlc_data->gmm_procedure_is_running ) + { + SET_STATE(TM, TM_PIM); + tm_delete_prim_queue(); + sig_tm_ru_reset_poll_array(); + TRACE_EVENT_P2("LLC QUEUE IS DISABLED, DELETE GMM PRIM QUEUE ps=%d pf=%d", + grlc_data->prim_start_tbf, + grlc_data->prim_start_free); + } + else + { + SET_STATE( TM, TM_ACCESS_PREPARED ); + } + } + + /*lint -fallthrough*/ + + case TM_PIM: + case TM_PAM: + case TM_PTM: + case TM_WAIT_4_PIM: + + grlc_data->tm.max_grlc_user_data = MAX_GRLC_USER_DATA ; + + if(cgrlc_enable_req->queue_mode EQ CGRLC_QUEUE_MODE_LLC) + { + UBYTE state = GET_STATE( TM ); + + if( state EQ TM_ACCESS_DISABLED OR + state EQ TM_ACCESS_PREPARED ) + { + SET_STATE( TM, TM_PIM ); + sig_tm_ru_reset_poll_array(); + } + if(grlc_data->gmm_procedure_is_running) + { + tm_get_llc_prim_queue(); + if ( (tm_prim_queue_get_free_count() > 0) AND + (grlc_data->prim_user_data <= grlc_data->tm.max_grlc_user_data)) + { + grlc_data->tm.send_grlc_ready_ind = SEND_A_GRLC_READY_IND; + } + else + { + grlc_data->tm.send_grlc_ready_ind = PRIM_QUEUE_FULL; + } + } + else + { + TRACE_EVENT("RESUME IS DONE"); + } + /* + * check if cell update is required + */ + if(cgrlc_enable_req->cu_cause EQ CGRLC_RA_CU) + { + TRACE_EVENT("CU REQ from GRR"); + /* + * Delete Empty frames + */ + if( grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE AND + ( grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_ptr->cause EQ GRLC_DTACS_EMPTY_FRAME OR + grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_ptr->cause EQ GRLC_DTACS_CELL_NOTIFI_NULL_FRAME ) ) + { + grlc_delete_prim(); + TRACE_EVENT("CEll_res: delete prim"); + } + grlc_data->uplink_tbf.access_type = CGRLC_AT_CELL_UPDATE; + } + tm_ul_tbf_ind(); + tm_handle_grlc_ready_ind(); + + } + + grlc_data->burst_type = cgrlc_enable_req->burst_type; + grlc_data->ab_type = cgrlc_enable_req->ab_type; + grlc_data->t3168_val = cgrlc_enable_req->t3168_val; + grlc_data->uplink_tbf.tlli = cgrlc_enable_req->ul_tlli; + grlc_data->uplink_tbf.ac_class = cgrlc_enable_req->ac_class; + grlc_data->downlink_tbf.tlli = cgrlc_enable_req->dl_tlli; + grlc_data->tm.change_mark = cgrlc_enable_req->change_mark; + +#ifdef REL99 + grlc_data->pfi_support = cgrlc_enable_req->pfi_support; + grlc_data->nw_rel = cgrlc_enable_req->nw_rel; +#endif + /* + * set N3102 to maximum value after cell reselction + */ + if(cgrlc_enable_req->v_pan_struct) + { + if(cgrlc_enable_req->pan_struct.pmax NEQ CGRLC_NO_UPDATE_N3102) + { + grlc_data->pan_struct = cgrlc_enable_req->pan_struct; + grlc_data->N3102 = cgrlc_enable_req->pan_struct.pmax; + } + } + else + { + grlc_data->pan_struct = cgrlc_enable_req->pan_struct; + grlc_data->N3102 = 0xFF; + } + if( grlc_data->uplink_tbf.tlli EQ (0xffffffff)) + { + TRACE_EVENT("GMM HAS UNASSIGNED GRR/GRLC, DELETE DATA QUEUE"); + /* + * delete prim queue + */ + while(grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL) + { + grlc_delete_prim(); + } + } + break; + default: + TRACE_ERROR( "CGRLC_ENABLE_REQ unexpected" ); + break; + } + PFREE(cgrlc_enable_req); + +} /* tm_cgrlc_enable_req() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_disable_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive cgrlc_disable_req +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_disable_req ( T_CGRLC_DISABLE_REQ *cgrlc_disable_req ) +{ + UBYTE state = GET_STATE( TM ); + + TRACE_FUNCTION( "tm_cgrlc_disable_req" ); + + grlc_data->tm.disable_class = cgrlc_disable_req->disable_class; + + switch( state ) + { + case TM_ACCESS_PREPARED: + SET_STATE(TM, TM_ACCESS_DISABLED); + break; + + case TM_ACCESS_DISABLED: + /* nothing to do */ + break; + + case TM_PIM: + case TM_WAIT_4_PIM: + SET_STATE(TM, TM_ACCESS_DISABLED); + + tm_handle_test_mode_cnf( grlc_test_mode_active( ) ); + + grlc_data->rel_type = REL_TYPE_NULL; + break; + + case TM_PTM: + tm_abort_tbf(grlc_data->tbf_type); + /* + * delete all poll positions + */ + sig_tm_ru_reset_poll_array(); + + /*lint -fallthrough*/ + + case TM_PAM: + SET_STATE(TM, TM_ACCESS_DISABLED); + + tm_handle_test_mode_cnf( grlc_test_mode_active( ) ); + + grlc_data->rel_type = REL_TYPE_NULL; + + if( state EQ TM_PAM AND cgrlc_disable_req->disable_class EQ CGRLC_DISABLE_CLASS_CR ) + { + tm_cgrlc_status_ind( CGRLC_TBF_ESTABLISHMENT_FAILURE ); + } + break; + + default: + TRACE_ERROR( "CGRLC_DISABLE_REQ unexpected" ); + break; + } + + if(cgrlc_disable_req->prim_status EQ CGRLC_PRIM_STATUS_ONE) + { + grlc_delete_prim(); + tm_handle_grlc_ready_ind(); + } + else if(cgrlc_disable_req->prim_status EQ CGRLC_PRIM_STATUS_ALL) + { + tm_delete_prim_queue(); + /* Reinitialize GRLC context + * 1. Delete Primitives + * 2. Abort TBF - (This is already done by GMMRR_SUSPEND_REQ) + * We reach this disable req only after releasing all TBFs + * 3. Reinitialize GRLC context */ + + TRACE_EVENT("Reinit GRLC"); + grlc_init(); + } + + + PFREE(cgrlc_disable_req); + +} /* tm_cgrlc_disable_req() */ + + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_ul_tbf_res ++------------------------------------------------------------------------------ +| Description : Handles the primitive cgrlc_ul_tbf_res +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_ul_tbf_res ( T_CGRLC_UL_TBF_RES *cgrlc_ul_tbf_res ) +{ + TRACE_FUNCTION( "tm_cgrlc_ul_tbf_res" ); + + tm_prcs_pwr_ctrl( &cgrlc_ul_tbf_res->pwr_ctrl ); + + /* + * Ignore the request for or modification of an UL TBF in case an UL TBF + * release request is currently sent to the data queue of GRR, it is just + * not yet processed, but TBF will be released anyway as one of the next + * steps. + */ + if( ( grlc_data->rel_type & REL_TYPE_UL ) EQ REL_TYPE_UL ) + { + TRACE_EVENT( "tm_cgrlc_ul_tbf_res: release of UL TBF requested in parallel" ); + + PFREE( cgrlc_ul_tbf_res ); + + return; + } + + vsi_t_stop(GRLC_handle,T3168); + grlc_data->tm.n_res_req = 0; + + switch( GET_STATE( TM ) ) + { + case TM_PAM: + switch(cgrlc_ul_tbf_res->tbf_mode) + { + case CGRLC_TBF_MODE_ESTABLISHMENT_FAILURE: /* establishment failure */ + SET_STATE(TM,TM_PIM); + grlc_delete_prim(); + sig_tm_ru_reset_poll_array(); + tm_cgrlc_status_ind(CGRLC_TBF_ESTABLISHMENT_FAILURE); + tm_handle_grlc_ready_ind(); + tm_ul_tbf_ind(); + break; + case CGRLC_TBF_MODE_ACCESS_FAILED: + if(cgrlc_ul_tbf_res->prim_status EQ CGRLC_PRIM_STATUS_ONE) + { + SET_STATE(TM,TM_PIM); + grlc_delete_prim(); + sig_tm_ru_reset_poll_array(); + tm_cgrlc_status_ind(CGRLC_PACKET_ACCESS_FAILURE); + tm_handle_grlc_ready_ind(); + tm_ul_tbf_ind(); + } + else if(cgrlc_ul_tbf_res->prim_status EQ CGRLC_PRIM_STATUS_ALL) + { + SET_STATE(TM,TM_PIM); + tm_delete_prim_queue(); + sig_tm_ru_reset_poll_array(); + tm_cgrlc_status_ind(CGRLC_PACKET_ACCESS_FAILURE); + tm_handle_grlc_ready_ind(); + tm_ul_tbf_ind(); + } + else if(cgrlc_ul_tbf_res->prim_status EQ CGRLC_PRIM_STATUS_TBF) + { + SET_STATE(TM,TM_PIM); + sig_tm_ru_reset_poll_array(); + tm_cgrlc_status_ind(CGRLC_PACKET_ACCESS_FAILURE); + tm_delete_prim_queue(); + tm_handle_grlc_ready_ind(); + tm_ul_tbf_ind(); + } + else + { + tm_handle_error_ra(); + tm_ul_tbf_ind(); + } + /* + * what happens to the existing tbfs + */ + break; + case CGRLC_TBF_MODE_UL: + case CGRLC_TBF_MODE_TMA: + case CGRLC_TBF_MODE_TMB: + SET_STATE(TM,TM_PTM); + if((grlc_data->testmode.mode EQ CGRLC_TEST_RANDOM) OR + (grlc_data->testmode.mode EQ CGRLC_LOOP)) + { + PALLOC(cgrlc_test_mode_ind,CGRLC_TEST_MODE_IND); /*T_CGRLC_TEST_MODE_IND*/ + cgrlc_test_mode_ind->test_mode_flag = grlc_data->testmode.mode; + PSEND(hCommGRR,cgrlc_test_mode_ind); + } + grlc_data->uplink_tbf.cs_type = (T_CODING_SCHEME)cgrlc_ul_tbf_res->cs_mode; + grlc_data->uplink_tbf.mac_mode = cgrlc_ul_tbf_res->mac_mode; + grlc_data->uplink_tbf.nts = cgrlc_ul_tbf_res->nts_max; + grlc_data->uplink_tbf.ts_mask = cgrlc_ul_tbf_res->tn_mask; + grlc_data->uplink_tbf.ti = cgrlc_ul_tbf_res->ti; + grlc_data->uplink_tbf.tlli_cs_type = cgrlc_ul_tbf_res->tlli_cs_mode; + grlc_data->uplink_tbf.bs_cv_max = cgrlc_ul_tbf_res->bs_cv_max; + grlc_data->r_bit = cgrlc_ul_tbf_res->r_bit; + + grlc_data->ul_tbf_start_time = cgrlc_ul_tbf_res->starting_time; + sig_tm_rd_ul_req_stop(); + sig_tm_meas_ptm(); + + tm_activate_tbf ( TBF_TYPE_UL ); + + if(cgrlc_ul_tbf_res->mac_mode) + { + grlc_data->uplink_tbf.fa_manag.fa_type = FA_NO_CURRENT; + tm_store_fa_bitmap(&cgrlc_ul_tbf_res->fix_alloc_struct); + } + + + if(!grlc_data->uplink_tbf.ti) + grlc_data->tm.n_acc_req_procedures = 0; + + grlc_data->tm.n_res_req = 0; + + grlc_data->uplink_tbf.rlc_db_granted = cgrlc_ul_tbf_res->rlc_db_granted; + + tm_tfi_handling (cgrlc_ul_tbf_res->starting_time,CGRLC_TBF_MODE_UL, cgrlc_ul_tbf_res->tfi, 0xFF); + sig_tm_ru_assign(); + if(cgrlc_ul_tbf_res->polling_bit NEQ 0xFF) + tm_handle_polling_bit(cgrlc_ul_tbf_res->starting_time,cgrlc_ul_tbf_res->polling_bit); + break; + default: + TRACE_ERROR("unexpected tbf mode in ul_tbf_res"); + break; + } + break; + case TM_PTM: + switch(cgrlc_ul_tbf_res->tbf_mode) + { + case CGRLC_TBF_MODE_ACCESS_FAILED: + if(cgrlc_ul_tbf_res->prim_status EQ CGRLC_PRIM_STATUS_ONE) + { + grlc_delete_prim(); + tm_cgrlc_status_ind(CGRLC_PACKET_ACCESS_FAILURE); + tm_handle_grlc_ready_ind(); + tm_ul_tbf_ind(); + } + else if(cgrlc_ul_tbf_res->prim_status EQ CGRLC_PRIM_STATUS_ALL) + { + tm_delete_prim_queue(); + tm_cgrlc_status_ind(CGRLC_PACKET_ACCESS_FAILURE); + tm_handle_grlc_ready_ind(); + tm_ul_tbf_ind(); + } + else if(cgrlc_ul_tbf_res->prim_status EQ CGRLC_PRIM_STATUS_TBF) + { + tm_cgrlc_status_ind(CGRLC_PACKET_ACCESS_FAILURE); + tm_delete_prim_queue(); + tm_handle_grlc_ready_ind(); + tm_ul_tbf_ind(); + } + else + { + tm_cgrlc_status_ind(CGRLC_PACKET_ACCESS_FAILURE); + tm_handle_error_ra(); + } + break; + case CGRLC_TBF_MODE_UL: + case CGRLC_TBF_MODE_TMA: + case CGRLC_TBF_MODE_TMB: + if((grlc_data->testmode.mode EQ CGRLC_TEST_RANDOM) OR + (grlc_data->testmode.mode EQ CGRLC_LOOP)) + { + PALLOC(cgrlc_test_mode_ind,CGRLC_TEST_MODE_IND); /*T_CGRLC_TEST_MODE_IND*/ + cgrlc_test_mode_ind->test_mode_flag = grlc_data->testmode.mode; + PSEND(hCommGRR,cgrlc_test_mode_ind); + } + + grlc_data->uplink_tbf.cs_type = (T_CODING_SCHEME)cgrlc_ul_tbf_res->cs_mode; + grlc_data->uplink_tbf.mac_mode = cgrlc_ul_tbf_res->mac_mode; + grlc_data->uplink_tbf.nts = cgrlc_ul_tbf_res->nts_max; + grlc_data->uplink_tbf.ts_mask = cgrlc_ul_tbf_res->tn_mask; + grlc_data->uplink_tbf.ti = cgrlc_ul_tbf_res->ti; + grlc_data->uplink_tbf.tlli_cs_type = cgrlc_ul_tbf_res->tlli_cs_mode; + grlc_data->uplink_tbf.bs_cv_max = cgrlc_ul_tbf_res->bs_cv_max; + +#if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH + if(grlc_data->tbf_type EQ TBF_TYPE_TP_ACCESS) + { + grlc_data->uplink_tbf.rlc_db_granted = cgrlc_ul_tbf_res->rlc_db_granted; + + if((grlc_data->testmode.mode EQ CGRLC_TEST_RANDOM) OR + (grlc_data->testmode.mode EQ CGRLC_LOOP)) + { + PALLOC(cgrlc_test_mode_ind,CGRLC_TEST_MODE_IND); /*T_CGRLC_TEST_MODE_IND*/ + cgrlc_test_mode_ind->test_mode_flag = grlc_data->testmode.mode; + PSEND(hCommGRR,cgrlc_test_mode_ind); + } + } + else +#endif + { + grlc_data->uplink_tbf.rlc_db_granted = 0; + } + + + grlc_data->tm.n_res_req = 0; + + grlc_data->ul_tbf_start_time = cgrlc_ul_tbf_res->starting_time; + sig_tm_rd_ul_req_stop(); + + tm_activate_tbf ( TBF_TYPE_UL ); + + if(cgrlc_ul_tbf_res->mac_mode) + { + tm_store_fa_bitmap(&cgrlc_ul_tbf_res->fix_alloc_struct); + } + + if(!grlc_data->uplink_tbf.ti) + grlc_data->tm.n_acc_req_procedures = 0; + + tm_tfi_handling (cgrlc_ul_tbf_res->starting_time,CGRLC_TBF_MODE_UL, cgrlc_ul_tbf_res->tfi, 0xFF); + + sig_tm_ru_assign(); + break; +#if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH + case CGRLC_TBF_MODE_2PA: + { + /*tbf establishment on PACCH*/ + grlc_data->ul_tbf_start_time = cgrlc_ul_tbf_res->starting_time; + tm_send_prr_2p_ptm(); + grlc_data->tm.pacch_prr_pca_sent = FALSE ; /* For Release of TBF , as two phase */ + } + break; +#endif + default: + TRACE_ERROR("unexpected tbf mode in ul_tbf_res"); + break; + } + break; + default: + TRACE_ERROR( "CGRLC_UL_TBF_RES unexpected" ); + break; + } + PFREE(cgrlc_ul_tbf_res); + +} /* tm_cgrlc_ul_tbf_res() */ + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_dl_tbf_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive cgrlc_dl_tbf_req +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_dl_tbf_req ( T_CGRLC_DL_TBF_REQ *cgrlc_dl_tbf_req ) +{ + UBYTE rd_state=GET_STATE( RD ); + TRACE_FUNCTION( "tm_cgrlc_dl_tbf_req" ); + + tm_prcs_pwr_ctrl( &cgrlc_dl_tbf_req->pwr_ctrl ); + grlc_data->downlink_tbf.trans_id++; + + /* + * Ignore the request for or modification of an DL TBF in case an DL TBF + * release request is currently sent to the data queue of GRR, it is just + * not yet processed, but TBF will be released anyway as one of the next + * steps. + */ + if( ( grlc_data->rel_type & REL_TYPE_DL ) EQ REL_TYPE_DL ) + { + /* The scenario T3192 expires before packet DL assignment message has been received + is handled.*/ + + TRACE_EVENT( "tm_cgrlc_dl_tbf_req: release of DL TBF requested in parallel" ); + + TRACE_EVENT( "Exception: T3192 expiry before PDA race condition, verify this" ); + grlc_data->rel_type &= ( ~ ( REL_TYPE_DL ) ); + + } + + switch( GET_STATE( TM ) ) + { + case TM_PAM: + case TM_PIM: + case TM_WAIT_4_PIM: + SET_STATE(TM,TM_PTM); + grlc_data->r_bit = 0; + + sig_tm_meas_ptm(); + + /*lint -fallthrough*/ + + case TM_PTM: + + if(cgrlc_dl_tbf_req->ctrl_ack_bit) + { + TRACE_EVENT("GRLC ctrl ack bit set"); + if((grlc_data->tbf_type EQ TBF_TYPE_UL) OR + (grlc_data->tbf_type EQ TBF_TYPE_NULL)) + { + TRACE_EVENT("DL ass will not be discarded in GRLC"); + } + { + sig_tm_rd_nor_rel(); + tm_deactivate_tbf(TBF_TYPE_DL); + grlc_data->dl_tfi = 0xFF; + } + } + else if (!cgrlc_dl_tbf_req->ctrl_ack_bit AND + (grlc_t_status(T3192) > 0) AND + #ifdef _TARGET_ + (grlc_t_status(T3192) < 25) + #else + (grlc_t_status(T3192) < 65) + #endif + ) + { + TRACE_EVENT_P1("XXXX accepting DL Ass T3192=%ld",grlc_t_status(T3192)); + if ( rd_state EQ RD_REL_ACK OR + rd_state EQ RD_REL_UACK ) + { + sig_tm_rd_nor_rel(); + tm_deactivate_tbf(TBF_TYPE_DL); + grlc_data->dl_tfi = 0xFF; + } + } + + grlc_data->downlink_tbf.rlc_mode = cgrlc_dl_tbf_req->rlc_mode; + grlc_data->downlink_tbf.cs_type = (T_CODING_SCHEME)cgrlc_dl_tbf_req->cs_mode; + grlc_data->downlink_tbf.mac_mode = cgrlc_dl_tbf_req->mac_mode; + grlc_data->downlink_tbf.nts = cgrlc_dl_tbf_req->nts_max; + grlc_data->downlink_tbf.ts_mask = cgrlc_dl_tbf_req->tn_mask; + grlc_data->downlink_tbf.t3192_val = cgrlc_dl_tbf_req->t3192_val; + + grlc_data->dl_tbf_start_time = cgrlc_dl_tbf_req->starting_time; + + tm_activate_tbf ( TBF_TYPE_DL ); + + tm_tfi_handling (cgrlc_dl_tbf_req->starting_time,CGRLC_TBF_MODE_DL,0xFF,cgrlc_dl_tbf_req->tfi); + + sig_tm_rd_assign(); + + + if(cgrlc_dl_tbf_req->polling_bit NEQ 0xFF) + tm_handle_polling_bit(cgrlc_dl_tbf_req->starting_time,cgrlc_dl_tbf_req->polling_bit); + + + tm_ul_tbf_ind(); /* dl tbf during access mode, ul tbf will be established over downlink*/ + break; + default: + { + /* This shall never happen, but in case, GRLC shall inform GRR about the + * immediate release of the TBF. Otherwise GRLC and GRR are running out + * of synchronisation and the whole system hangs. + */ + PALLOC( cgrlc_tbf_rel_ind, CGRLC_TBF_REL_IND ); + + TRACE_ERROR( "CGRLC_DL_TBF_REQ unexpected, so send release ind!" ); + + cgrlc_tbf_rel_ind->tbf_mode = CGRLC_TBF_MODE_DL; + cgrlc_tbf_rel_ind->tbf_rel_cause = CGRLC_TBF_REL_ABNORMAL; + cgrlc_tbf_rel_ind->v_c_value = FALSE; + cgrlc_tbf_rel_ind->dl_trans_id = grlc_data->downlink_tbf.trans_id; + + PSEND( hCommGRR, cgrlc_tbf_rel_ind ); + } + break; + } + PFREE(cgrlc_dl_tbf_req); + +} /* tm_cgrlc_dl_tbf_req() */ + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_tbf_rel_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive cgrlc_tbf_rel_req +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_tbf_rel_req ( T_CGRLC_TBF_REL_REQ *cgrlc_tbf_rel_req ) +{ + BOOL rel_ul = FALSE; + BOOL rel_dl = FALSE; + BOOL mod_ul = FALSE; + BOOL mod_dl = FALSE; + + + TRACE_FUNCTION( "tm_cgrlc_tbf_rel_req" ); + + + switch( GET_STATE( TM ) ) + { + case TM_PTM: + /* + * 1. abnomal release uplink --> immediate release + * 2. normal release uplink --> normal tbf release after current pdu is transmitted + * 3. abnormal release downlink no poll --> immediate release + * 4. abnormal release downlink with poll--> release after poll is sent + * release both tbfs in case of testmode B + */ + + if( (cgrlc_tbf_rel_req->tbf_mode EQ CGRLC_TBF_MODE_UL) OR + (cgrlc_tbf_rel_req->tbf_mode EQ CGRLC_TBF_MODE_DL_UL) +#if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH + OR + (cgrlc_tbf_rel_req->tbf_mode EQ CGRLC_TBF_MODE_2PA) +#endif + ) + { + if(grlc_data->testmode.mode EQ CGRLC_LOOP) + { + rel_ul = TRUE; + rel_dl = TRUE; + } + else + { + if(cgrlc_tbf_rel_req->tbf_rel_cause EQ CGRLC_TBF_REL_ABNORMAL) + { + rel_ul = TRUE; + } + else + { + mod_ul = TRUE; + } + } + + } + if( (cgrlc_tbf_rel_req->tbf_mode EQ CGRLC_TBF_MODE_DL) OR + (cgrlc_tbf_rel_req->tbf_mode EQ CGRLC_TBF_MODE_DL_UL)) + { + if(grlc_data->testmode.mode EQ CGRLC_LOOP) + { + rel_ul = TRUE; + rel_dl = TRUE; + } + else + { + if(cgrlc_tbf_rel_req->rel_fn EQ CGRLC_STARTING_TIME_NOT_PRESENT) + { + rel_dl = TRUE; + } + else + { + mod_dl = TRUE; + } + } + + } + + if(mod_ul) + { + if(grlc_data->ru.next_prim < PRIM_QUEUE_SIZE_TOTAL) + { + grlc_data->prim_queue[grlc_data->ru.next_prim].start_new_tbf = 1; + TRACE_EVENT_P5("QUEUE_STATUS BEFORE start=%d,next=%d active=%d rlc_oct=%ld sdu_len=%ld" + ,grlc_data->prim_start_tbf + ,grlc_data->ru.next_prim + ,grlc_data->ru.active_prim + ,grlc_data->ru.rlc_octet_cnt + ,grlc_data->ru.sdu_len); + sig_tm_ru_queue_status(); + TRACE_EVENT_P5("QUEUE_STATUS AFTER start=%d,next=%d active=%d rlc_oct=%ld sdu_len=%ld" + ,grlc_data->prim_start_tbf + ,grlc_data->ru.next_prim + ,grlc_data->ru.active_prim + ,grlc_data->ru.rlc_octet_cnt + ,grlc_data->ru.sdu_len); + } + } + if ( rel_ul AND + (cgrlc_tbf_rel_req->rel_fn NEQ CGRLC_STARTING_TIME_NOT_PRESENT)) + { + sig_tm_ru_abrel(cgrlc_tbf_rel_req->rel_fn, TRUE); + mod_ul = TRUE; + rel_ul = FALSE; + } + + if(mod_dl) + { + sig_tm_rd_abrel(cgrlc_tbf_rel_req->rel_fn, TRUE); + } + + + if(rel_dl AND rel_ul) + { + tm_abort_tbf(grlc_data->tbf_type); + } + else if(rel_dl) + { + tm_abort_tbf(TBF_TYPE_DL); + } + else if(rel_ul) + { +#if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH + if(grlc_data->tbf_type EQ TBF_TYPE_TP_ACCESS ) + tm_abort_tbf(TBF_TYPE_TP_ACCESS); + else +#endif + tm_abort_tbf(TBF_TYPE_UL); + } + + + if(grlc_data->tbf_type EQ TBF_TYPE_NULL) + { + SET_STATE(TM,TM_WAIT_4_PIM); + sig_tm_ru_reset_poll_array(); + } + break; + default: + TRACE_ERROR( "CGRLC_TBF_REL_REQ unexpected" ); + break; + } + PFREE(cgrlc_tbf_rel_req); + +} /* tm_cgrlc_tbf_rel_req() */ + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_tbf_rel_res ++------------------------------------------------------------------------------ +| Description : Handles the primitive cgrlc_tbf_rel_res +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_tbf_rel_res ( T_CGRLC_TBF_REL_RES *cgrlc_tbf_rel_res ) +{ + +#if !defined (NTRACE) + + BOOL trace = FALSE; + T_REL_TYPE rel_type = grlc_data->rel_type; + +#endif /* #if !defined (NTRACE) */ + + TRACE_FUNCTION( "tm_cgrlc_tbf_rel_res" ); + + /* + * Check for consistency: Only requested releases shall be indicated by GRR. + */ + if( cgrlc_tbf_rel_res->tbf_mode EQ CGRLC_TBF_MODE_DL_UL OR + cgrlc_tbf_rel_res->tbf_mode EQ CGRLC_TBF_MODE_DL ) + { + if( ( grlc_data->rel_type & REL_TYPE_DL ) EQ REL_TYPE_DL ) + { + grlc_data->rel_type &= ( ~ ( REL_TYPE_DL ) ); + } + +#if !defined (NTRACE) + + else + { + trace = TRUE; + } + +#endif /* #if !defined (NTRACE) */ + + } + + /* + * Check for consistency: Only requested releases shall be indicated by GRR. + */ + if( cgrlc_tbf_rel_res->tbf_mode EQ CGRLC_TBF_MODE_DL_UL OR + cgrlc_tbf_rel_res->tbf_mode EQ CGRLC_TBF_MODE_UL ) + { + if( ( grlc_data->rel_type & REL_TYPE_UL ) EQ REL_TYPE_UL ) + { + grlc_data->rel_type &= ( ~ ( REL_TYPE_UL ) ); + } + +#if !defined (NTRACE) + + else + { + trace = TRUE; + } + +#endif /* #if !defined (NTRACE) */ + + } + +#if !defined (NTRACE) + + /* + * Inconsistency deteced. + */ + if( trace EQ TRUE ) + { + TRACE_EVENT_P3 + ( "tm_cgrlc_tbf_rel_res: unexpected release response - tbf_mode = %d, rel_type (old) = %d, rel_type (new) = %d", + cgrlc_tbf_rel_res->tbf_mode, rel_type, grlc_data->rel_type ); + } + +#endif /* #if !defined (NTRACE) */ + + if( grlc_data->rel_type EQ REL_TYPE_NULL ) + { + switch( GET_STATE( TM ) ) + { + case TM_ACCESS_DISABLED: + case TM_ACCESS_PREPARED: + break; + case TM_WAIT_4_PIM: + SET_STATE(TM,TM_PIM); + sig_tm_ru_reset_poll_array(); + tm_handle_test_mode_cnf( grlc_data->testmode.mode EQ CGRLC_TEST_MODE_RELEASE ); + grlc_data->tm.n_res_req = 0; + + /*lint -fallthrough*/ + + case TM_PIM: + /* + * reset ta value + */ + grlc_data->ta_value = 0xFF; + + /*lint -fallthrough*/ + + case TM_PTM: + tm_ul_tbf_ind(); + break; + default: + TRACE_ERROR( "CGRLC_TBF_REL_RES unexpected" ); + break; + } + } + PFREE(cgrlc_tbf_rel_res); + +} /* tm_cgrlc_tbf_rel_res() */ + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_data_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive cgrlc_data_req +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_data_req ( T_CGRLC_DATA_REQ *cgrlc_data_req ) +{ + TRACE_FUNCTION( "tm_cgrlc_data_req" ); + + + switch( GET_STATE( TM ) ) + { + case TM_PAM: + case TM_PTM: + tm_store_ctrl_blk( cgrlc_data_req->blk_owner, ( void* )cgrlc_data_req->data_array ) ; + break; + default: + TRACE_ERROR( "CGRLC_DATA_REQ unexpected" ); + break; + } + PFREE(cgrlc_data_req); + +} /* tm_cgrlc_data_req() */ + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_poll_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive cgrlc_poll_req +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_poll_req ( T_CGRLC_POLL_REQ *cgrlc_poll_req ) +{ + TRACE_FUNCTION( "tm_cgrlc_poll_req" ); + + + switch( GET_STATE( TM ) ) + { + case TM_PAM: + /* + * handle cpap polling bit, no save pass directly to layer1, poll will + * be sent with the first call + */ + + grlc_data->next_poll_fn = cgrlc_poll_req->poll_fn; + grlc_data->ul_poll_pos_index = 0; + + if(grlc_data->burst_type NEQ CGRLC_BURST_TYPE_NB) + { + grlc_send_access_burst(cgrlc_poll_req->tn); + } + else + { + T_U_GRLC_CTRL_ACK u_ctrl_ack; /* built pca, do not use ccd, because IA is stored*/ + u_ctrl_ack.msg_type = U_GRLC_CTRL_ACK_c; + u_ctrl_ack.pctrl_ack = cgrlc_poll_req->ctrl_ack; + grlc_set_buf_tlli( &u_ctrl_ack.tlli_value, grlc_data->uplink_tbf.tlli ); + + grlc_send_normal_burst((UBYTE *)&u_ctrl_ack, NULL, cgrlc_poll_req->tn); + } + + break; + case TM_PTM: + grlc_save_poll_pos(cgrlc_poll_req->poll_fn, + cgrlc_poll_req->tn, + 0xFF, + cgrlc_poll_req->poll_b_type, + cgrlc_poll_req->ctrl_ack); + break; + default: + TRACE_ERROR( "CGRLC_POLL_REQ unexpected" ); + break; + } + PFREE(cgrlc_poll_req); + +} /* tm_cgrlc_poll_req() */ + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_access_status_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive cgrlc_access_status_req +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_access_status_req ( T_CGRLC_ACCESS_STATUS_REQ *cgrlc_access_status_req ) +{ + TRACE_FUNCTION( "tm_cgrlc_access_status_req" ); + + + switch( GET_STATE( TM ) ) + { + case TM_PIM: + case TM_PAM: + tm_ul_tbf_ind(); + break; + default: + TRACE_ERROR( "CGRLC_ACCESS_STATUS_REQ unexpected" ); + break; + } + PFREE(cgrlc_access_status_req); + +} /* tm_cgrlc_access_status_req() */ + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_test_mode_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive cgrlc_test_mode_req +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_test_mode_req ( T_CGRLC_TEST_MODE_REQ *cgrlc_test_mode_req ) +{ + UBYTE pdus_to_queue; + UBYTE count = 0; + + TRACE_FUNCTION( "tm_cgrlc_test_mode_req" ); + + TRACE_EVENT_P1( "cgrlc_test_mode_req test mode is activ %x",cgrlc_test_mode_req->test_mode_flag); + + switch( GET_STATE( TM ) ) + { + case TM_PIM: + case TM_PTM: + /* + * save the test mode data + */ + + grlc_data->testmode.mode = cgrlc_test_mode_req->test_mode_flag; + + grlc_data->testmode.n_pdu = (ULONG)cgrlc_test_mode_req->no_of_pdus; + grlc_data->testmode.dl_ts_offset = cgrlc_test_mode_req->dl_timeslot_offset; + + + if (grlc_data->testmode.mode EQ CGRLC_LOOP) + { + TRACE_EVENT("testmode b"); + switch(grlc_data->tbf_type) + { + case TBF_TYPE_DL: + /* + * request uplink tbf over existing DL + */ + tm_queue_test_mode_prim(1); + /* + * set received buffer to special values + */ + grlc_data->testmode.rec_data[0].block_status = 0xFEFE; + grlc_data->testmode.rec_data[0].e_bit = 0xFE; + memset(grlc_data->testmode.rec_data[0].payload, 0xFE,50); + grlc_data->testmode.rec_data[1].block_status = 0xFEFE; + grlc_data->testmode.rec_data[1].e_bit = 0xFE; + memset(grlc_data->testmode.rec_data[1].payload, 0xFE,50); + /* + * If the "Downlink Timeslot Offset" is set to 3, TN3 shall be treated as the first downlink + * timeslot if a TBF is established in TN3. If TN3 does not support a TBF, the first active + * timeslot after TN3 shall be treated as the first downlink timeslot. The counting sequence + * is continuous through TN7 and TN0. + */ + while (!((0x80>>grlc_data->testmode.dl_ts_offset) & grlc_data->dl_tn_mask) && (count < 8)) + { + if (grlc_data->testmode.dl_ts_offset > 7) + grlc_data->testmode.dl_ts_offset = (UBYTE)-1; + grlc_data->testmode.dl_ts_offset++; + count++; + } + TRACE_EVENT_P1 ("downlink timeslot offset is %d", grlc_data->testmode.dl_ts_offset); + break; + default: + TRACE_EVENT_P1("unexpected tbf type for testmode B:tbf_type=%d",grlc_data->tbf_type); + break; + } + + } + else /* it is testmode A with regular PDU amount */ + { + if (grlc_data->testmode.n_pdu EQ 0) + { + /* + * In case of Testmode A and 0 PDUs are requested the MS may + * optionally interprete this as infinitive duration TBF. + */ + TRACE_EVENT("testmode a infinite"); + grlc_data->testmode.n_pdu -= 1; + } + else + { + TRACE_EVENT_P1("testmode a %ld pdus",grlc_data->testmode.n_pdu); + } + /* + * (PRIM_QUEUE_SIZE-1) to avoid the full prime queue situation in test mode. + * It should also not be more then 50*64 byte, which are queue here. + * The remainig PDUs will be queued when a PDU is completely transmitted. + */ + if (grlc_data->testmode.n_pdu < (PEI_PRIM_QUEUE_SIZE/2)) + { + pdus_to_queue = (UBYTE) grlc_data->testmode.n_pdu; + grlc_data->testmode.n_pdu = 0; + } + else + { + pdus_to_queue = (PEI_PRIM_QUEUE_SIZE/2); + grlc_data->testmode.n_pdu -= (PEI_PRIM_QUEUE_SIZE/2); + } + /* + * generation of pseudo primitve to start the test mode tbf TBF + */ + tm_queue_test_mode_prim(pdus_to_queue); + + grlc_prbs(INITIALIZE, 0, 0); + if(!grlc_data->testmode.ptr_test_data) + { + MALLOC(grlc_data->testmode.ptr_test_data,50/*Max. RLC Block Length*/); + } + } + + break; + default: + TRACE_ERROR( "CGRLC_TEST_MODE_REQ unexpected" ); + TRACE_EVENT_P1("tm state %d", grlc_data->tm.state); + break; + } + + + PFREE(cgrlc_test_mode_req); + +} /* tm_cgrlc_test_mode_req() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_test_end_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive CGRLC_TEST_END_REQ +| GRLC have to leave the test mode. The leaving procedure is +| finished with the transmission of GMMRR_TEST_MODE_CNF +| Parameters : *gmmrr_suspend_req - Ptr to primitive payload +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_test_end_req ( T_CGRLC_TEST_END_REQ *cgrlc_test_end_req ) +{ + TRACE_FUNCTION( "tm_cgrlc_test_end_req" ); + + tm_abort_tbf( grlc_data->tbf_type ); + + /* + * delete all primitives in queue. + */ + tm_delete_prim_queue(); + + SET_STATE(TM,TM_WAIT_4_PIM); + + grlc_data->tm.n_acc_req_procedures = 0; + grlc_data->tm.n_res_req = 0; /* reset counter of resource requests during access */ + + PFREE(cgrlc_test_end_req); + +} /* tm_cgrlc_test_end_req() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_ta_value_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive cgrlc_ta_value_req +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_ta_value_req ( T_CGRLC_TA_VALUE_REQ *cgrlc_ta_value_req ) +{ + TRACE_FUNCTION( "tm_cgrlc_ta_value_req" ); + + grlc_data->ta_value = cgrlc_ta_value_req->ta_value; + + PFREE(cgrlc_ta_value_req); + +} /* tm_cgrlc_ta_value_req() */ + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_ready_timer_config_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive tm_cgrlc_ready_timer_config_req +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_ready_timer_config_req + ( T_CGRLC_READY_TIMER_CONFIG_REQ *cgrlc_ready_timer_config_req ) +{ + TRACE_FUNCTION( "tm_cgrlc_ready_timer_config_req" ); + + grlc_data->ready_timer.handling = READY_TIMER_HANDLING_ENABLED; + grlc_data->ready_timer.value = cgrlc_ready_timer_config_req->t3314_val; + + if( grlc_data->ready_timer.value EQ CGRLC_DEACTIVATED ) + { + grlc_enter_ready_state( ); + } + + PFREE(cgrlc_ready_timer_config_req); + +} /* (tm_cgrlc_ready_timer_config_req) */ + +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_force_to_standby_req ++------------------------------------------------------------------------------ +| Description : Handles the primitive tm_cgrlc_force_to_standby_req +| +| Parameters : void +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_force_to_standby_req + ( T_CGRLC_FORCE_TO_STANDBY_REQ *cgrlc_force_to_standby_req ) +{ + TRACE_FUNCTION( "tm_cgrlc_force_to_standby_req" ); + + /* + * By receiving this primitive the Ready Timer State will be forced to Standby and + * the running Ready Timer will be stopped + */ + grlc_enter_standby_state( ); + + PFREE(cgrlc_force_to_standby_req); + +} /* (tm_cgrlc_force_to_standby_req) */ +/* ++------------------------------------------------------------------------------ +| Function : tm_cgrlc_pwr_ctrl_req ++------------------------------------------------------------------------------ +| Description : +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void tm_cgrlc_pwr_ctrl_req ( T_CGRLC_PWR_CTRL_REQ *pwr_ctrl_req ) +{ + TRACE_FUNCTION( "tm_cgrlc_pwr_ctrl_req" ); + + tm_prcs_pwr_ctrl( &pwr_ctrl_req->pwr_ctrl ); + + PFREE( pwr_ctrl_req ); + +} /* tm_cgrlc_pwr_ctrl_req */