FreeCalypso > hg > fc-magnetite
view src/g23m-gprs/grlc/grlc_rus.c @ 208:ab79cf3c29a5
AT-over-RVTMUX mechanism ported over to the TCS3.2 version of ACI
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 14 Oct 2016 17:15:08 +0000 |
parents | 219afcfc6250 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | 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 signal handler functions for service | RU of entity GRLC. +----------------------------------------------------------------------------- */ #ifndef GRLC_RUS_C #define GRLC_RUS_C #endif #define ENTITY_GRLC /*==== INCLUDES =============================================================*/ #include <stdio.h> #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 "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" #include "grlc.h" /* to get the global entity definitions */ #include "grlc_f.h" #include "grlc_tms.h" #include "grlc_ruf.h" #include <string.h> /*==== CONST ================================================================*/ /*#ifdef TRACE_ERROR #undef TRACE_ERROR #define TRACE_ERROR(x) #endif #ifdef TRACE_FUNCTION #undef TRACE_FUNCTION #define TRACE_FUNCTION(x) #endif #ifdef TRACE_ISIG #undef TRACE_ISIG #define TRACE_ISIG(x) #endif*/ /*==== LOCAL VARS ===========================================================*/ /*==== PRIVATE FUNCTIONS ====================================================*/ /*==== PUBLIC FUNCTIONS =====================================================*/ /* +------------------------------------------------------------------------------ | Function : sig_tm_ru_assign +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_TM_RU_ASSIGN | | Parameters : dummy - description of parameter dummy | +------------------------------------------------------------------------------ */ GLOBAL void sig_tm_ru_assign ( void) { TRACE_ISIG( "sig_tm_ru_assign" ); switch( GET_STATE( RU ) ) { case RU_WAIT_FOR_FIRST_CALL_ACK: case RU_WAIT_FOR_FIRST_CALL_UACK: /* * reorg l1 one */ { grlc_data->ru.write_pos_index -= grlc_data->ru.nts_max; } TRACE_EVENT_P3("UL REASSIG during tbf starting time is running:%ld ul_tfi=%d st_fn_tfi=%d" ,grlc_data->ul_tbf_start_time ,grlc_data->ul_tfi ,grlc_data->start_fn_ul_tfi); /*lint -fallthrough*/ case RU_NULL: if(grlc_data->ul_tfi EQ 0xFF) grlc_data->ul_tfi = grlc_data->start_fn_ul_tfi; switch( grlc_data->uplink_tbf.rlc_mode ) { case CGRLC_RLC_MODE_ACK: SET_STATE(RU,RU_WAIT_FOR_FIRST_CALL_ACK); ru_tbf_init(); /* * sending the first block of the tbf */ grlc_data->ru.N3104 = 0; while( grlc_data->ru.nts AND tm_get_num_ctrl_blck( ) NEQ 0 ) { /* * next uplink block is a control block, * check if countdown procedure is statred or not */ ru_send_control_block( ); } while(grlc_data->ru.nts AND grlc_data->ru.sdu_len) { ru_new_data(); } while(grlc_data->ru.nts) { ru_ret_bsn(); } break; case CGRLC_RLC_MODE_UACK: SET_STATE(RU,RU_WAIT_FOR_FIRST_CALL_UACK); ru_tbf_init(); while( grlc_data->ru.nts AND tm_get_num_ctrl_blck( ) NEQ 0 ) { /* * next uplink block is a control block, * check if countdown procedure is statred or not */ ru_send_control_block( ); } while(grlc_data->ru.nts AND grlc_data->ru.sdu_len) { ru_new_data(); } if(grlc_data->ru.cv EQ 0) { while( grlc_data->ru.nts AND (grlc_data->ru.count_cv_0 < 4) ) { UBYTE bsn; bsn = grlc_data->ru.vs - 1; bsn &= 0x7F; ru_send_mac_data_req(bsn); grlc_data->ru.count_cv_0++; } } break; default: TRACE_ERROR( "unknown RLC MODE for UL" ); break; } break; case RU_ACK: case RU_REL_ACK: case RU_UACK: case RU_REL_UACK: /* * store new params, modification at reaching starting time */ grlc_data->ru.next_tbf_params = grlc_data->uplink_tbf; grlc_data->ru.v_next_tbf_params = TRUE; break; default: TRACE_ERROR( "SIG_TM_RU_ASSIGN unexpected" ); break; } } /* sig_tm_ru_assign() */ /* +------------------------------------------------------------------------------ | Function : sig_tm_ru_abrel +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_TM_RU_ABREL | | Parameters : dummy - description of parameter dummy | +------------------------------------------------------------------------------ */ GLOBAL void sig_tm_ru_abrel (ULONG fn,BOOL poll_i) { TRACE_ISIG( "sig_tm_ru_abrel" ); /* * stop all uplink timers */ vsi_t_stop(GRLC_handle,T3164); vsi_t_stop(GRLC_handle,T3166); vsi_t_stop(GRLC_handle,T3180); vsi_t_stop(GRLC_handle,T3182); vsi_t_stop(GRLC_handle,T3184);/*timer for FA, used in simulation test*/ vsi_t_stop(GRLC_handle,T3188);/*timer for FA, used in simulation test*/ if (grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL) { grlc_data->prim_queue[grlc_data->prim_start_tbf].rlc_status = FALSE; grlc_data->prim_queue[grlc_data->prim_start_tbf].cv_status = FALSE; grlc_data->prim_queue[grlc_data->prim_start_tbf].last_bsn = 0xFF; } if(!poll_i) { /* * abnormal release: abort TBF */ grlc_data->tbf_ctrl[grlc_data->ul_index].end_fn = grlc_data->ul_fn; grlc_data->tbf_ctrl[grlc_data->ul_index].vs_vr = grlc_data->ru.vs; grlc_data->tbf_ctrl[grlc_data->ul_index].va_vq = grlc_data->ru.va; grlc_data->tbf_ctrl[grlc_data->ul_index].cnt_ts = grlc_data->ru.cnt_ts; grlc_trace_tbf_par ( grlc_data->ul_index ); SET_STATE(RU,RU_NULL); } else { SET_STATE(RU,RU_NET_REL); grlc_data->ru.poll_fn = fn; TRACE_EVENT_P2("UL:RU_NET_REL p.tbf rel c_fn=%ld poll_fn=%d",grlc_data->dl_fn,grlc_data->ru.poll_fn); } } /* sig_tm_ru_abrel() */ /* +------------------------------------------------------------------------------ | Function : sig_tm_ru_queue_status +------------------------------------------------------------------------------ | Description : Handles the internal signal SIG_TM_RU_QUEUE_STATUS | | Parameters : dummy - description of parameter dummy | +------------------------------------------------------------------------------ */ GLOBAL void sig_tm_ru_queue_status ( void) { TRACE_ISIG( "sig_tm_ru_queue_status" ); switch( GET_STATE( RU ) ) { case RU_WAIT_FOR_FIRST_CALL_ACK: case RU_WAIT_FOR_FIRST_CALL_UACK: case RU_ACK: case RU_UACK: grlc_data->ru.rlc_octet_cnt = ru_recalc_rlc_oct_cnt(); break; default: /* * nothing to do */ break; } } /* sig_tm_ru_queue_status() */ /* +------------------------------------------------------------------------------ | Function : sig_gff_ru_ul_ack +------------------------------------------------------------------------------ | Description : Handles the Signal SIG_GFF_RU_UL_ACK | | Parameters : fn - current frame number | tn - current timeslot number | rrbp - rrbp parameter indicated in mac header | sp - sp parameter indicated in mac header | +------------------------------------------------------------------------------ */ GLOBAL void sig_gff_ru_ul_ack (ULONG fn , UBYTE tn, UBYTE rrbp, UBYTE sp) { MCAST(d_ul_ack,D_GRLC_UL_ACK); TRACE_ISIG( "sig_gff_ru_ul_ack" ); #ifdef REL99 /* Handling abnormal case * 8.7 While a TBF is in progress, if a mobile station receives a * PACKET UPLINK ASSIGNMENT, PACKET UPLINK ACK/NACK or PACKET TIMESLOT RECONFIGURE * message with message escape bit indicating EGPRS (resp. GPRS) contents whereas * the current TBF mode is GPRS (resp. EGPRS), the mobile station shall ignore the * message. */ if(d_ul_ack->egprs_flag) { TRACE_ERROR( "EGPRS UL ACK/NACK received" ); return; } #endif grlc_data->tbf_ctrl[grlc_data->ul_index].ack_cnt++; if(grlc_data->uplink_tbf.mac_mode EQ CGRLC_MAC_MODE_FA) { vsi_t_stop(GRLC_handle,T3184); if(!d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.f_ack_ind) { vsi_t_start(GRLC_handle,T3184,T3184_VALUE); TRACE_EVENT("sig_gff_ru_ul_ack: T3184 started for FA"); } sig_ru_tm_repeat_alloc(); } switch( GET_STATE( RU ) ) { case RU_ACK : if(ru_contention_resolution()) { SET_STATE(RU,RU_NULL); return; } ru_update_vb(); grlc_data->ru.va = ru_calc_va(); ru_delete_prims(grlc_data->ru.va); ru_handle_stall_ind(); break; case RU_REL_ACK : /* * For proper release of ul tbf */ vsi_t_stop(GRLC_handle,T3182); if(ru_contention_resolution()) { SET_STATE(RU,RU_NULL); return; } if(sp) { grlc_data->ru.poll_fn = grlc_calc_new_poll_pos(fn,rrbp); grlc_data->ru.poll_tn = tn; } if( !(d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.f_ack_ind) ) { ru_update_vb(); grlc_data->ru.va = ru_calc_va(); ru_delete_prims(grlc_data->ru.va); ru_handle_stall_ind(); } else if(d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.f_ack_ind AND grlc_data->ru.cv EQ 0) { SET_STATE(RU,RU_SEND_PCA); ru_delete_prims(grlc_data->ru.vs); grlc_data->ru.va = grlc_data->ru.vs; grlc_data->ru.nr_nacked_blks = 0; grlc_data->tbf_ctrl[grlc_data->ul_index].fbi = 1; grlc_data->ru.reorg_l1_needed = TRUE; /* delete blocks, dummies will be placed */ if(!sp) { SET_STATE(RU,RU_NULL); TRACE_EVENT("FAI = 1 received but no poll"); vsi_t_stop(GRLC_handle,T3180); sig_ru_tm_error_ra(); } #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH else { /* network wishes to re-estab tbf on pacch */ if(d_ul_ack->gprs_ul_ack_nack_info.release_99_str_d_ul_ack.tbf_est EQ 1 AND grlc_data->prim_start_tbf NEQ END_OF_LIST AND /*UL data is present*/ grlc_data->tbf_type NEQ TBF_TYPE_CONC /* No DL TBF */ ) { grlc_data->ru.tbf_re_est = TRUE; grlc_data->next_poll_array[grlc_data->poll_start_tbf].poll_type[tn] = CGRLC_POLL_RE_ASS; } } #endif } else { /* * if the mobile station has not started or has not completed the countdown procedure * and it receives a Packet Uplink Ack/Nack with the Final Ack Indicator set, * it shall perform an abnormal release with random access. */ SET_STATE(RU,RU_NULL); TRACE_ERROR( "FBI set, but cv > 0" ); sig_ru_tm_error_ra(); } break; case RU_UACK: grlc_data->ru.va = grlc_data->ru.vs; ru_handle_stall_ind(); break; case RU_REL_UACK: /* * For proper release of ul tbf */ vsi_t_stop(GRLC_handle,T3182); grlc_data->ru.va = grlc_data->ru.vs; ru_handle_stall_ind(); if(sp) { grlc_data->ru.poll_fn = grlc_calc_new_poll_pos(fn,rrbp); grlc_data->ru.poll_tn = tn; if( d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.f_ack_ind) { SET_STATE(RU,RU_SEND_PCA); ru_delete_prims(grlc_data->ru.vs); #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH if(d_ul_ack->gprs_ul_ack_nack_info.release_99_str_d_ul_ack.tbf_est EQ 1 AND grlc_data->prim_start_tbf NEQ END_OF_LIST AND /*UL data is present*/ grlc_data->tbf_type NEQ TBF_TYPE_CONC /* No DL TBF */ ) { grlc_data->ru.tbf_re_est = TRUE; grlc_data->next_poll_array[grlc_data->poll_start_tbf].poll_type[tn] = CGRLC_POLL_RE_ASS; } #endif } } /* * this part is a workaround to pass GCF 14.16.1 * R&S is not setting the sp bit in final ack */ else if( d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.f_ack_ind AND (grlc_data->ru.cv EQ 0) AND (grlc_data->testmode.mode EQ CGRLC_TEST_RANDOM)) { TRACE_EVENT("SP bit not set in PULACK, FBI BIT SET --> PERFORM IMMEDIATE RELEASE DURING TMA"); sig_ru_tm_error_ra(); } else if( d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.f_ack_ind AND (grlc_data->testmode.mode EQ CGRLC_TEST_RANDOM)) { TRACE_EVENT_P3("SP=0,FBI=1,CV=%d-> rlc_oct=%ld,sdu_l=%ld" ,grlc_data->ru.cv ,grlc_data->ru.rlc_octet_cnt ,grlc_data->ru.sdu_len); } break; case RU_SEND_PCA : if(sp) { grlc_data->ru.poll_fn = grlc_calc_new_poll_pos(fn,rrbp); grlc_data->ru.poll_tn = tn; TRACE_EVENT_P1("NEW RU POLL FN AT =%ld ",grlc_data->ru.poll_fn); #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH /* * tbf re-establishment on pacch */ if( d_ul_ack->gprs_ul_ack_nack_info.release_99_str_d_ul_ack.tbf_est EQ 1 AND /* network wishes to re-estab tbf on pacch */ grlc_data->prim_start_tbf NEQ END_OF_LIST AND /* ul data is present*/ grlc_data->tbf_type NEQ TBF_TYPE_CONC /* no dl tbf */ ) { grlc_data->ru.tbf_re_est = TRUE; grlc_data->next_poll_array[grlc_data->poll_start_tbf].poll_type[tn] = CGRLC_POLL_RE_ASS; } #endif } break; default: TRACE_ERROR( "SIG_GFF_RU_UL_ACK unexpected" ); break; } if(grlc_data->ru.cs_type NEQ (T_CODING_SCHEME)d_ul_ack->gprs_ul_ack_nack_info.chan_coding_cmd) { TRACE_EVENT_P7("ul ack:CS changed from %d to %d, ssn=%d, va=%d, vs=%d, neg_acked_blks=%d, fbi=%d ", grlc_data->ru.cs_type, d_ul_ack->gprs_ul_ack_nack_info.chan_coding_cmd, d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.ssn, grlc_data->ru.va, grlc_data->ru.vs, grlc_data->ru.nr_nacked_blks, d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.f_ack_ind); grlc_data->ru.cs_type = (T_CODING_SCHEME)d_ul_ack->gprs_ul_ack_nack_info.chan_coding_cmd; ru_change_of_cs(grlc_data->ru.cs_type); } else if(grlc_data->ru.nr_nacked_blks OR d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.f_ack_ind) { ULONG rbb=0,i,dummy; for(i=0; i<d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.ssn;i++) { dummy = (USHORT)d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.rbb[WIN_SIZE-1-i]; rbb += dummy <<i; if(i EQ 31) break; } TRACE_EVENT_P8("ul ack fn=%ld :ssn=%d,va=%d,vs=%d,neg_acked_blks=%d,fbi=%d,rbb=%lx,cnt_ts=%d", fn, d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.ssn, grlc_data->ru.va, grlc_data->ru.vs, grlc_data->ru.nr_nacked_blks, d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.f_ack_ind, rbb, grlc_data->ru.cnt_ts); } grlc_data->ru.bsn_ret = grlc_data->ru.va; } /* sig_gff_ru_ul_ack() */ /* +------------------------------------------------------------------------------ | Function : sig_gff_ru_mac_ready_ind +------------------------------------------------------------------------------ | Description : Handles the Signal SIG_GFF_RU_MAC_READY_IND | | Parameters : *ptr_mac_ready_ind_i - Ptr to primitive MAC_READY_IND | +------------------------------------------------------------------------------ */ GLOBAL void sig_gff_ru_mac_ready_ind ( T_MAC_READY_IND * mac_ul_ready_ind) { UBYTE bsn=0xFF; BOOL release_tbf=FALSE; UBYTE rd_state=GET_STATE( RD ); UBYTE ctrl_blk_active_idx; BOOL realloc_prr_allowed = FALSE; TRACE_ISIG( "sig_gff_ru_mac_ready_ind" ); #if defined (_SIMULATION_) TRACE_EVENT_P1("fn = %ld",mac_ul_ready_ind->fn ); TRACE_EVENT_P9("wpi=%d sent=%ld\n current.cnt=%d,bsn[0]=%d,bsn[1]=%d,bsn[2]=%d,bsn[3]=%d,nts=%d,nts_max=%d", grlc_data->ru.write_pos_index, mac_ul_ready_ind->rlc_blocks_sent, grlc_data->ru.pl_retrans_current.cnt, grlc_data->ru.pl_retrans_current.blk[0], grlc_data->ru.pl_retrans_current.blk[1], grlc_data->ru.pl_retrans_current.blk[2], grlc_data->ru.pl_retrans_current.blk[3], grlc_data->ru.nts, grlc_data->ru.nts_max); #endif /* defined (_SIMULATION_) */ ru_switch_ul_buffer (mac_ul_ready_ind->rlc_blocks_sent); ru_check_pl_ret(mac_ul_ready_ind->rlc_blocks_sent); if(grlc_data->ru.v_next_tbf_params AND grlc_check_if_tbf_start_is_elapsed ( grlc_data->ul_tbf_start_time, ((mac_ul_ready_ind->fn+5)%FN_MAX))) { ru_handle_tbf_start_in_ptm( mac_ul_ready_ind->rlc_blocks_sent); ru_cgrlc_st_time_ind(); } grlc_handle_poll_pos (mac_ul_ready_ind->fn); ru_handle_nts (mac_ul_ready_ind->rlc_blocks_sent); switch( GET_STATE( RU ) ) { case RU_WAIT_FOR_FIRST_CALL_ACK: if( !grlc_data->ru.v_next_tbf_params AND !grlc_check_if_tbf_start_is_elapsed ( grlc_data->ul_tbf_start_time, ((mac_ul_ready_ind->fn+5)%FN_MAX))) { TRACE_EVENT_P2("WAIT FOR UL STARTING TIME, DL IS RUNNING st=%ld c_fn=%ld",grlc_data->ul_tbf_start_time ,mac_ul_ready_ind->fn); grlc_send_rem_poll_pos(mac_ul_ready_ind->fn); return; } if(grlc_data->ru.first_usf) { /* * Tbf starting time is reached, start T3164 */ vsi_t_start(GRLC_handle,T3164,T3164_VALUE); } SET_STATE(RU,RU_ACK); grlc_data->tbf_ctrl[grlc_data->ul_index].start_fn = mac_ul_ready_ind->fn; if(!grlc_data->ru.cd_active AND (grlc_data->ru.tbc <= grlc_data->uplink_tbf.bs_cv_max)) { grlc_data->ru.cd_active = TRUE; ru_set_prim_queue(grlc_data->ru.cd_active); } ru_cgrlc_st_time_ind(); TRACE_EVENT_P9 ("UL first call:fn=%ld (%ld) tfi=%d ul_mask=%x st_fn=%ld pdu_cnt=%d,PST=%d,PSF=%d ta=%d", mac_ul_ready_ind->fn, mac_ul_ready_ind->fn%42432, grlc_data->ul_tfi, grlc_data->ul_tn_mask, grlc_data->ul_tbf_start_time, grlc_data->grlc_data_req_cnt, grlc_data->prim_start_tbf, grlc_data->prim_start_free, grlc_data->ta_value); /*lint -fallthrough*/ case RU_ACK : /* * Handling of counter N3104 */ if(ru_handle_n3104()) { SET_STATE(RU,RU_NULL); TRACE_ERROR( "counter N3104 reaches its maximum, contention resolution has failed" ); TRACE_EVENT_P7("va=%d,vs=%d,cnt_ts=%d,fn=%d n3104_max=%d,n3104=%d,bs_cv_max=%d", grlc_data->ru.va, grlc_data->ru.vs, grlc_data->ru.cnt_ts, mac_ul_ready_ind->fn, grlc_data->ru.N3104_MAX, grlc_data->ru.N3104, grlc_data->uplink_tbf.bs_cv_max); sig_ru_tm_error_ra(); return; } /* * IS THERE A CONTROL BLOCK TO SEND ? */ while( grlc_data->ru.nts AND !grlc_data->ru.cd_active AND tm_get_num_ctrl_blck( ) NEQ 0 ) { /* * next uplink block is a control block, * check if countdown procedure is statred or not */ ru_send_control_block( ); } /* * IS RETRANSMISSION NEEDED ? */ while(grlc_data->ru.nts) { ctrl_blk_active_idx = ru_peek_for_ctrl_blk(); if ((ctrl_blk_active_idx EQ 0xFF) OR realloc_prr_allowed EQ TRUE) /*No control block , form data block*/ { while( (grlc_data->ru.vb[grlc_data->ru.bsn_ret & WIN_MOD] EQ VB_NACKED) AND grlc_data->ru.nts) { ru_ret_bsn(); } while(grlc_data->ru.nts) { /* * IS THERE A STALL CONDITION ? */ if(grlc_data->ru.vs EQ ((grlc_data->ru.va + WIN_SIZE) & 0x7F)) { ru_stall_ind(); } /* * IS THERE MORE DATA ? */ else if(grlc_data->ru.sdu_len) { ru_new_data(); } else { break; } } realloc_prr_allowed = FALSE; break; } else { TRACE_EVENT_P1("reallocation of llc pdu (index)=%d",ctrl_blk_active_idx); /* if already one PRR in L1 Buffer , replace it with new PRR */ if (grlc_data->ru.pl_retrans_current.blk[0] EQ (BLK_INDEX_TM + OFFSET_CTRL_BLOCK_IDX)) { grlc_data->ru.write_pos_index--; grlc_data->ru.pl_retrans_current.cnt--; grlc_data->ru.nts++; TRACE_EVENT("prr in l1 buffer queue,replace with new prr"); } sig_ru_tm_end_of_pdu(ctrl_blk_active_idx); ru_send_control_block(); realloc_prr_allowed = TRUE; } } if( grlc_data->ru.cv EQ 0) { SET_STATE(RU,RU_REL_ACK); grlc_data->ru.bsn_ret = grlc_data->ru.va; } while(grlc_data->ru.nts) { ru_ret_bsn(); } grlc_send_rem_poll_pos (mac_ul_ready_ind->fn); break; case RU_REL_ACK : /* * All blocks are sent, wait for the last ack. * If uplink resources are available retransmit window */ if(ru_handle_n3104()) { SET_STATE(RU,RU_NULL); TRACE_ERROR( "counter N3104 reaches its maximum, contention resolution has failed" ); sig_ru_tm_error_ra(); grlc_data->ru.nts = 0; /*to avoid transmitting of data*/ return; } /* * IS THERE A CONTROL BLOCK TO SEND ? */ while( grlc_data->ru.nts AND tm_get_num_ctrl_blck( ) NEQ 0 AND ru_ctrl_blk_selection_allowed()) { /* * next uplink block is a control block, */ TRACE_EVENT("Ctrl blk selected in RU_REL_ACK"); ru_send_control_block( ); } while(grlc_data->ru.nts) { ctrl_blk_active_idx = ru_peek_for_ctrl_blk(); if ((ctrl_blk_active_idx EQ 0xFF) OR realloc_prr_allowed EQ TRUE) /*No control block , form data block*/ { while(grlc_data->ru.nts AND (grlc_data->ru.va NEQ grlc_data->ru.vs)) { ru_ret_bsn(); } while(grlc_data->ru.nts) { TRACE_EVENT_P3("ALL BLKS ACKED, wait for fbi in PUAN wpi=%d t3182=%d t3180=%d" ,grlc_data->ru.write_pos_index ,grlc_t_status( T3182 ) ,grlc_t_status( T3180 )); ru_send_ul_dummy_block(); } realloc_prr_allowed = FALSE; break; } else { TRACE_EVENT_P1("reallocation of llc pdu (index)=%d",ctrl_blk_active_idx); /* if already one PRR in L1 Buffer , replace it with new PRR */ if (grlc_data->ru.pl_retrans_current.blk[0] EQ (BLK_INDEX_TM + OFFSET_CTRL_BLOCK_IDX)) { grlc_data->ru.write_pos_index--; grlc_data->ru.pl_retrans_current.cnt--; grlc_data->ru.nts++; TRACE_EVENT("prr in l1 buffer queue,replace with new prr"); } sig_ru_tm_end_of_pdu(ctrl_blk_active_idx); ru_send_control_block(); realloc_prr_allowed = TRUE; } } grlc_send_rem_poll_pos (mac_ul_ready_ind->fn); break; case RU_SEND_PCA: while(grlc_data->ru.nts) { ru_send_ul_dummy_block(); } #ifdef _TARGET_ if( grlc_check_dist(mac_ul_ready_ind->fn,grlc_data->ru.poll_fn,100) ) { if ((mac_ul_ready_ind->fn NEQ grlc_data->ru.poll_fn) AND (mac_ul_ready_ind->last_poll_resp EQ 0)) { release_tbf = TRUE; /*TRACE_EVENT_P2("REL TBF:fn =%ld new ru_poll_fn=%ld", mac_ul_ready_ind->fn, grlc_data->ru.poll_fn);*/ } else if(mac_ul_ready_ind->last_poll_resp) { grlc_data->ru.poll_fn +=104; grlc_data->ru.poll_fn %= FN_MAX; TRACE_ERROR("UL GAP: UL TBF NOT RELEASED +104"); TRACE_EVENT_P3("fn =%ld new ru_poll_fn=%ld poll_staus=%d", mac_ul_ready_ind->fn, grlc_data->ru.poll_fn, mac_ul_ready_ind->last_poll_resp); } if(grlc_data->missed_poll_fn EQ grlc_data->ru.poll_fn) { release_tbf = FALSE; grlc_data->ru.poll_fn +=104; grlc_data->ru.poll_fn %= FN_MAX; TRACE_ERROR("DL GAP: UL TBF NOT RELEASED +104"); TRACE_EVENT_P3("fn =%ld missed poll=%ld new ru_poll_fn=%ld", mac_ul_ready_ind->fn, grlc_data->missed_poll_fn, grlc_data->ru.poll_fn); } } #endif #ifdef _SIMULATION_ if(mac_ul_ready_ind->fn EQ grlc_data->ru.poll_fn) release_tbf = TRUE; #endif grlc_send_rem_poll_pos (mac_ul_ready_ind->fn); if(release_tbf) { vsi_t_stop(GRLC_handle,T3182); vsi_t_stop(GRLC_handle,T3180); if ( grlc_data->poll_start_tbf NEQ 0xFF AND (!grlc_check_if_tbf_start_is_elapsed(grlc_data->dl_tbf_start_time,grlc_data->next_poll_array[grlc_data-> poll_start_tbf].fn) AND (rd_state EQ RD_WAIT_FOR_STARTING_TIME_ACK OR rd_state EQ RD_WAIT_FOR_STARTING_TIME_UACK)) ) { grlc_data->ru.poll_fn = grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn; TRACE_EVENT_P2("UL DELAYED WHILE WAITING STARTING TIME DL poll_fn=%ld c_fn=%ld",grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn ,mac_ul_ready_ind->fn); } else { SET_STATE(RU,RU_NULL); grlc_data->tbf_ctrl[grlc_data->ul_index].end_fn = grlc_data->ul_fn; grlc_data->tbf_ctrl[grlc_data->ul_index].vs_vr = grlc_data->ru.vs; grlc_data->tbf_ctrl[grlc_data->ul_index].va_vq = grlc_data->ru.va; grlc_data->tbf_ctrl[grlc_data->ul_index].cnt_ts = grlc_data->ru.cnt_ts; grlc_trace_tbf_par ( grlc_data->ul_index ); #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH if(grlc_data->ru.tbf_re_est) { /* * signal tm to start timer 3168,re-establish tbf on pacch as poll sent succesfully */ sig_ru_tm_ul_re_est_tbf(); } else #endif { sig_ru_tm_end_of_tbf(); } } } break; case RU_WAIT_FOR_FIRST_CALL_UACK: if( !grlc_data->ru.v_next_tbf_params AND !grlc_check_if_tbf_start_is_elapsed ( grlc_data->ul_tbf_start_time, ((mac_ul_ready_ind->fn+5)%FN_MAX))) { TRACE_EVENT_P2("UACK MODE WAIT FOR UL STARTING TIME, DL IS RUNNING st=%ld c_fn=%ld",grlc_data->ul_tbf_start_time ,mac_ul_ready_ind->fn); grlc_send_rem_poll_pos(mac_ul_ready_ind->fn); return; } if(grlc_data->ru.first_usf) { /* * Tbf starting time is reached, start T3164 */ vsi_t_start(GRLC_handle,T3164,T3164_VALUE); } grlc_data->tbf_ctrl[grlc_data->ul_index].start_fn = mac_ul_ready_ind->fn; SET_STATE(RU,RU_UACK); if(!grlc_data->ru.cd_active AND (grlc_data->ru.tbc <= grlc_data->uplink_tbf.bs_cv_max)) { grlc_data->ru.cd_active = TRUE; ru_set_prim_queue(grlc_data->ru.cd_active); } ru_cgrlc_st_time_ind(); TRACE_EVENT_P9 ("UL first call:fn=%ld (%ld) tfi=%d ul_mask=%x st_fn=%ld pdu_cnt=%d,PST=%d,PSF=%d ta=%d UACK_MODE", mac_ul_ready_ind->fn, mac_ul_ready_ind->fn%42432, grlc_data->ul_tfi, grlc_data->ul_tn_mask, grlc_data->ul_tbf_start_time, grlc_data->grlc_data_req_cnt, grlc_data->prim_start_tbf, grlc_data->prim_start_free, grlc_data->ta_value); /*lint -fallthrough*/ case RU_UACK : ru_del_prim_in_uack_mode ( mac_ul_ready_ind->rlc_blocks_sent); if(grlc_data->ru.last_bsn EQ LAST_BSN_STALL_CONDITION) { /*in uack mode is transmission at stall condition of data not allowed*/ grlc_data->ru.nts = 0; } else if (grlc_data->ru.last_bsn EQ LAST_BSN_RESUME_UACK_MODE_AFTER_SI) { /* data transmission allowed after stall indication in rlc unackgnowledged mode*/ grlc_data->ru.nts = grlc_data->ru.nts_max; grlc_data->ru.last_bsn = LAST_BSN_NOT_BULIT; TRACE_EVENT(" STALL IND ELIMINATED IN RLC UACK"); } /* * IS THERE A CONTROL BLOCK TO SEND ? */ while( grlc_data->ru.nts AND !grlc_data->ru.cd_active AND tm_get_num_ctrl_blck( ) NEQ 0 ) { ru_send_control_block( ); } /* * IS THERE MORE DATA ? */ while(grlc_data->ru.nts) { ctrl_blk_active_idx = ru_peek_for_ctrl_blk(); if ((ctrl_blk_active_idx EQ 0xFF) OR realloc_prr_allowed EQ TRUE) /*No control block , form data block*/ { while( grlc_data->ru.nts AND grlc_data->ru.sdu_len ) { ru_new_data(); } if (grlc_test_mode_active()) { /* * to prevent stall indication in Testmode A/B */ grlc_data->ru.va = grlc_data->ru.vs; } while( grlc_data->ru.nts AND (grlc_data->ru.count_cv_0 < 4) ) { bsn = (grlc_data->ru.vs - 1) % 128; ru_send_mac_data_req(bsn); grlc_data->ru.count_cv_0++; } while(grlc_data->ru.nts) { ru_send_ul_dummy_block(); } realloc_prr_allowed = FALSE; break; } else { TRACE_EVENT_P1("reallocation of llc pdu (index)=%d",ctrl_blk_active_idx); /* if already one PRR in L1 Buffer , replace it with new PRR */ if (grlc_data->ru.pl_retrans_current.blk[0] EQ (BLK_INDEX_TM + OFFSET_CTRL_BLOCK_IDX)) { grlc_data->ru.write_pos_index--; grlc_data->ru.pl_retrans_current.cnt--; grlc_data->ru.nts++; TRACE_EVENT("prr in l1 buffer queue,replace with new prr"); } sig_ru_tm_end_of_pdu(ctrl_blk_active_idx); ru_send_control_block(); realloc_prr_allowed = TRUE; } } if(grlc_data->ru.cv EQ 0) { SET_STATE(RU,RU_REL_UACK); } grlc_send_rem_poll_pos (mac_ul_ready_ind->fn); break; case RU_REL_UACK: ru_del_prim_in_uack_mode ( mac_ul_ready_ind->rlc_blocks_sent); /* * IS THERE A CONTROL BLOCK TO SEND ? */ while( grlc_data->ru.nts AND tm_get_num_ctrl_blck( ) NEQ 0 AND ru_ctrl_blk_selection_allowed()) { /* * next uplink block is a control block, */ TRACE_EVENT("Ctrl blk selected in RU_REL_UACK"); ru_send_control_block( ); } while(grlc_data->ru.nts) { ctrl_blk_active_idx = ru_peek_for_ctrl_blk(); if ((ctrl_blk_active_idx EQ 0xFF) OR realloc_prr_allowed EQ TRUE) /*No control block , form data block*/ { while( grlc_data->ru.nts AND (grlc_data->ru.count_cv_0 < 4) ) { bsn = (grlc_data->ru.vs - 1) % 128; ru_send_mac_data_req(bsn); grlc_data->ru.count_cv_0++; } while(grlc_data->ru.nts) { ru_send_ul_dummy_block(); } realloc_prr_allowed = FALSE; break; } else { TRACE_EVENT_P1("reallocation of llc pdu (index)=%d",ctrl_blk_active_idx); /* if already one PRR in L1 Buffer , replace it with new PRR */ if (grlc_data->ru.pl_retrans_current.blk[0] EQ (BLK_INDEX_TM + OFFSET_CTRL_BLOCK_IDX)) { grlc_data->ru.write_pos_index--; grlc_data->ru.pl_retrans_current.cnt--; grlc_data->ru.nts++; TRACE_EVENT("prr in l1 buffer queue,replace with new prr"); } sig_ru_tm_end_of_pdu(ctrl_blk_active_idx); ru_send_control_block(); realloc_prr_allowed = TRUE; } } grlc_send_rem_poll_pos (mac_ul_ready_ind->fn); break; case RU_NET_REL: /* * send packet control acknowledgement and abort TBF */ grlc_send_rem_poll_pos(mac_ul_ready_ind->fn); if(grlc_data->ru.release_tbf) { SET_STATE(RU,RU_NULL); grlc_data->ru.release_tbf = FALSE; TRACE_EVENT_P2("poll sent after packet tbf release(UL): current_fn=%ld rel_fn=%ld", mac_ul_ready_ind->fn, grlc_data->ru.poll_fn); vsi_t_stop(GRLC_handle,T3180); vsi_t_stop(GRLC_handle,T3182); grlc_data->tbf_ctrl[grlc_data->ul_index].end_fn = grlc_data->ul_fn; grlc_data->tbf_ctrl[grlc_data->ul_index].vs_vr = grlc_data->ru.vs; grlc_data->tbf_ctrl[grlc_data->ul_index].va_vq = grlc_data->ru.va; grlc_data->tbf_ctrl[grlc_data->ul_index].cnt_ts = grlc_data->ru.cnt_ts; grlc_trace_tbf_par ( grlc_data->ul_index ); sig_ru_tm_end_of_tbf(); } if(grlc_check_if_tbf_start_is_elapsed ( grlc_data->ru.poll_fn, mac_ul_ready_ind->fn)) { grlc_data->ru.release_tbf = TRUE; TRACE_EVENT_P2("wait for poll confirm after packet tbf release(UL) current_fn=%ld rel_fn=%ld", mac_ul_ready_ind->fn, grlc_data->ru.poll_fn); } break; default: TRACE_ERROR( "MAC_UL_READY_IND unexpected" ); break; } if(grlc_data->uplink_tbf.mac_mode EQ CGRLC_MAC_MODE_FA AND grlc_data->uplink_tbf.fa_manag.current_alloc.alloc_end_fn EQ mac_ul_ready_ind->fn) { sig_ru_tm_end_of_fix_alloc(); } } /* sig_gff_ru_mac_ready_ind() */ /* +------------------------------------------------------------------------------ | Function : sig_tm_ru_reset_poll_array +------------------------------------------------------------------------------ | Description : Handles the Signal SIG_TM_RU_RESET_POLL_ARRAY. | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void sig_tm_ru_reset_poll_array() { UBYTE i,j; /* * handle not_transmitted control blocks */ for (i=0;i<NEXT_POLL_ARRAY_SIZE;i++) { /* * set free list */ grlc_data->next_poll_array[i].next = i+1; grlc_data->next_poll_array[i].fn = 0xFFFFFFFF; grlc_data->next_poll_array[i].cnt = 0; for(j=0; j< POLL_TYPE_ARRAY_SIZE; j++) { grlc_data->next_poll_array[i].poll_type[j] = CGRLC_POLL_NONE; } } /* * last free entry points to 0xff */ grlc_data->next_poll_array[NEXT_POLL_ARRAY_SIZE-1].next = 0xFF; /* * indicates invalid paramters */ grlc_data->poll_start_free = 0; grlc_data->poll_start_tbf = 0xFF; }