view src/g23m-gprs/grlc/grlc_rus.c @ 600:8f50b202e81f

board preprocessor conditionals: prep for more FC hw in the future This change eliminates the CONFIG_TARGET_FCDEV3B preprocessor symbol and all preprocessor conditionals throughout the code base that tested for it, replacing them with CONFIG_TARGET_FCFAM or CONFIG_TARGET_FCMODEM. These new symbols are specified as follows: CONFIG_TARGET_FCFAM is intended to cover all hardware designs created by Mother Mychaela under the FreeCalypso trademark. This family will include modem products (repackagings of the FCDEV3B, possibly with RFFE or even RF transceiver changes), and also my desired FreeCalypso handset product. CONFIG_TARGET_FCMODEM is intended to cover all FreeCalypso modem products (which will be firmware-compatible with the FCDEV3B if they use TI Rita transceiver, or will require a different fw build if we switch to one of Silabs Aero transceivers), but not the handset product. Right now this CONFIG_TARGET_FCMODEM preprocessor symbol is used to conditionalize everything dealing with MCSI. At the present moment the future of FC hardware evolution is still unknown: it is not known whether we will ever have any beyond-FCDEV3B hardware at all (contingent on uncertain funding), and if we do produce further FC hardware designs, it is not known whether they will retain the same FIC modem core (triband), if we are going to have a quadband design that still retains the classic Rita transceiver, or if we are going to switch to Silabs Aero II or some other transceiver. If we produce a quadband modem that still uses Rita, it will run exactly the same fw as the FCDEV3B thanks to the way we define TSPACT signals for the RF_FAM=12 && CONFIG_TARGET_FCFAM combination, and the current fcdev3b build target will be renamed to fcmodem. OTOH, if that putative quadband modem will be Aero-based, then it will require a different fw build target, the fcdev3b target will stay as it is, and the two targets will both define CONFIG_TARGET_FCFAM and CONFIG_TARGET_FCMODEM, but will have different RF_FAM numbers. But no matter which way we are going to evolve, it is not right to have conditionals on CONFIG_TARGET_FCDEV3B in places like ACI, and the present change clears the way for future evolution.
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 01 Apr 2019 01:05:24 +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;  
}