view src/g23m-fad/rlp/rlp_rbm.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 90eb61ecd093
children
line wrap: on
line source

/* 
+----------------------------------------------------------------------------- 
|  Project :  CSD (8411)
|  Modul   :  Rlp_rbm.c
+----------------------------------------------------------------------------- 
|  Copyright 2002 Texas Instruments Berlin, AG 
|                 All rights reserved. 
| 
|                 This file is confidential and a trade secret of Texas 
|                 Instruments Berlin, AG 
|                 The receipt of or possession of this file does not convey 
|                 any rights to reproduce or disclose its contents or to 
|                 manufacture, use, or sell anything it may describe, in 
|                 whole, or in part, without the specific written consent of 
|                 Texas Instruments Berlin, AG. 
+----------------------------------------------------------------------------- 
|  Purpose :  This Modul defines the receive buffer manager for
|             the component Radio Link Protocol of the base station
+----------------------------------------------------------------------------- 
*/ 

#ifndef RLP_RBM_C
#define RLP_RBM_C
#endif

#define ENTITY_RLP

/*==== INCLUDES ===================================================*/

#include <string.h>
#include "typedefs.h"
#include "vsi.h"
#include "custom.h"
#include "gsm.h"
#include "cus_rlp.h"
#include "prim.h"
#include "tok.h"
#include "rlp.h"

/*==== CONST =======================================================*/

/*==== TYPES =======================================================*/

/*==== VAR EXPORT ==================================================*/

/*==== VAR LOCAL ===================================================*/

/*==== FUNCTIONS ===================================================*/

/*
+------------------------------------------------------------------------------
|  Function    : rbmi_alloc_curr_prim
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


LOCAL void rbmi_alloc_curr_prim
           (
             void
           )
{
  USHORT sduSize = rlp_data->rbm.FramesPerPrim
                 * rlp_data->rbm.FrameSize * 8;

  PALLOC_SDU
  (
    rlp_data_ind,
    RLP_DATA_IND,
    sduSize
  );

  TRACE_FUNCTION ("rbmi_alloc_curr_prim()");

  rlp_data_ind->sdu.l_buf
    = rlp_data->rbm.FramesPerPrim * rlp_data->rbm.FrameSize * 8;

  rlp_data_ind->data_size = rlp_data->rbm.FrameSize - HEADER_LEN - TRAILER_LEN;

  rlp_data->rbm.CurrPrim    = rlp_data_ind;
  rlp_data->rbm.CurrPrimCou = 0;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbmi_pq_enq
+------------------------------------------------------------------------------
|  Description : A primitive is put into the primitive queue. This is done
|                in rbm_buffer_all_in_sequence_frames when the current
|                primitive is filled up.
|
|
|  Parameters  : prim -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


LOCAL void rbmi_pq_enq
           (
             T_RBM_PRIM *prim
           )
{
  TRACE_FUNCTION ("rbmi_pq_enq()");

  rlp_data->rbm.PQ_Array[rlp_data->rbm.PQ_Write] = prim;

  rlp_data->rbm.PQ_Write = (rlp_data->rbm.PQ_Write+1) % RBM_PQ_SIZE;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbmi_copy_frame_to_sdu
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : frame -
|                sdu   -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


LOCAL void rbmi_copy_frame_to_sdu(T_RBM_FRAMEPTR frame, T_sdu *sdu)
{
  TRACE_FUNCTION ("rbmi_copy_frame_to_sdu()");

  memcpy(sdu->buf+(sdu->o_buf>>3), frame, rlp_data->rbm.FrameSize);

  sdu->o_buf += rlp_data->rbm.FrameSize * 8;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbmi_buffer_frame
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : fromSlot     -
|                primIsReady  -
|
|  Return      : -
+------------------------------------------------------------------------------
*/


LOCAL void rbmi_buffer_frame
           (
             T_RBM_BUFFER_EXTIDX  fromSlot,
             BOOL                *primIsReady
           )
{
  TRACE_FUNCTION ("rbmi_buffer_frame()");

  rbmi_copy_frame_to_sdu
  (
    rlp_data->rbm.Slot[fromSlot].Frame,
    &rlp_data->rbm.CurrPrim->sdu
  );

  if (++rlp_data->rbm.CurrPrimCou EQ rlp_data->rbm.FramesPerPrim)
  {
    rlp_data->rbm.CurrPrim->sdu.o_buf = 0;
    rbmi_pq_enq (rlp_data->rbm.CurrPrim);
    rbmi_alloc_curr_prim ();
    *primIsReady = TRUE;
  }
}


/*
+------------------------------------------------------------------------------
|  Function    : rbmi_pq_deq
+------------------------------------------------------------------------------
|  Description :  A rlp_data_ind primitive is taken from the queue. This
|                 is done when the queue is not empty and a RLP_GETDATA_REQ
|                 is executed. Of after storing a primitive in the queue,
|                 when the upper layer is waiting for data.
|
|  Parameters  : prim  -
|
|
|  Return      : TRUE  -
|                FALSE -
+------------------------------------------------------------------------------
*/


LOCAL BOOL rbmi_pq_deq
           (
             T_RBM_PRIM **prim
           )
{
  TRACE_FUNCTION ("rbmi_pq_deq()");

  if (rlp_data->rbm.PQ_Read NEQ rlp_data->rbm.PQ_Write)
  {
    *prim = rlp_data->rbm.PQ_Array[rlp_data->rbm.PQ_Read];
    rlp_data->rbm.PQ_Array[rlp_data->rbm.PQ_Read] = (T_RBM_PRIM *) NULL;

    rlp_data->rbm.PQ_Read = (rlp_data->rbm.PQ_Read+1) % RBM_PQ_SIZE;
    return TRUE;
  }
  else
  {
    /*
     * prim buffer is empty
     */
    return FALSE;
  }
}

/*
+------------------------------------------------------------------------------
|  Function    : rbmi_pq_check
+------------------------------------------------------------------------------
|  Description : The prim queue is checked.
|                rcvReady indicates that there is still more than the
|                minimum space in the queue.
|                rcvFull  indicates that the queue is completeley full.
|
|
|  Parameters  : rcvReady -
|                rcvFull  -
|
|  Return      : -
+------------------------------------------------------------------------------
*/


LOCAL void rbmi_pq_check
           (
             BOOL *rcvReady,
             BOOL *rcvFull
           )
{
  T_RBM_PQ_INDEX writeMax, writeThresh;

  TRACE_FUNCTION ("rbmi_pq_check()");

  writeMax    = (rlp_data->rbm.PQ_Read + RBM_PQ_MAX_PRIM)
              % RBM_PQ_SIZE;

  writeThresh = (rlp_data->rbm.PQ_Read + RBM_PQ_THRE_RNR)
              % RBM_PQ_SIZE;

  /*
   * prim queue filled upto threshold?
   */

  if (!(XOR
        (
          XOR
          (
            writeThresh > rlp_data->rbm.PQ_Write,
            rlp_data->rbm.PQ_Write > writeMax
          ),
          writeThresh > writeMax
        )
       )
      )
  {
    *rcvReady = FALSE;

    *rcvFull  = (rlp_data->rbm.PQ_Write EQ writeMax);
  }
  else
  {
    *rcvFull = FALSE;
    *rcvReady = TRUE;
  }
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_set_wind_size
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : windSize -
|
|
|  Return      : TRUE  -
|                FALSE -
+------------------------------------------------------------------------------
*/


GLOBAL BOOL rbm_set_wind_size
            (
              T_RBM_BUFFER_INDEX windSize
            )
{
  BOOL resetTimers;
  T_RBM_BUFFER_INDEX n;
  T_RBM_BUFFER_INDEX nEnd;
  T_RBM_BUFFER_INDEX oldSize;

  TRACE_FUNCTION ("rbm_set_wind_size()");

  resetTimers = FALSE;
  oldSize = rlp_data->rbm.K;
  rlp_data->rbm.K = windSize;

  if (windSize < oldSize)
  {
    n = rlp_data->rbm.VR + windSize;
    if (n >= RBM_BUF_SIZE)
    {
      n -= RBM_BUF_SIZE;
    }
    nEnd = rlp_data->rbm.VR + oldSize;
    if (nEnd >= RBM_BUF_SIZE)
    {
      nEnd -= RBM_BUF_SIZE;
    }
    do
    {
      switch (rlp_data->rbm.Slot[n].R_State)
      {
      case RBM_SREJ:
      case RBM_WAIT:
        resetTimers = TRUE;
        rlp_data->rbm.Slot[n].R_State = RBM_IDLE;
        break;
      default:
        break;
      }
      n += 1;
      if (n >= RBM_BUF_SIZE)
      {
        n = 0;
      }

    } while (n NEQ nEnd);
  }
  return (resetTimers);
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_init
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : windSize      -
|                frameSize     -
|                framesPerPrim -
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_init
            (
              T_RBM_BUFFER_INDEX windSize,
              USHORT             frameSize,
              USHORT             framesPerPrim
            )
{
  USHORT n;

  TRACE_FUNCTION ("rbm_init()");

  n = 0;

  rlp_data->rbm.FramesPerPrim = framesPerPrim;
  rlp_data->rbm.FrameSize     = frameSize;

  for (n = 0; n < RBM_BUF_SIZE; n++)
  {
    rlp_data->rbm.Slot[n].R_State = RBM_IDLE;

    memset
    (
      rlp_data->rbm.Slot[n].Frame,
      0,
      rlp_data->rbm.FrameSize
    );
  }

  rlp_data->rbm.VR          = 0;
  rlp_data->rbm.FrameInRiBu = FALSE;

  memset
  (
    rlp_data->rbm.Frame,
    0,
    rlp_data->rbm.FrameSize
  );

  for (n = 0; n < RBM_PQ_SIZE; n++)
    rlp_data->rbm.PQ_Array[n] = (T_RBM_PRIM *) NULL;


  rlp_data->rbm.PQ_Read  = 0;
  rlp_data->rbm.PQ_Write = 0;

  rbmi_alloc_curr_prim ();
  rlp_data->rbm.K = windSize;

  rlp_data->rbm.Initialised = TRUE;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_deinit
+------------------------------------------------------------------------------
|  Description : This function frees all allocated T_RBM_PRIM primitives
|                of the receive buffer manager.
|
|  Parameters  :
|
|
|  Return      :
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_deinit
            (
              void
            )
{
  TRACE_FUNCTION ("rbm_deinit()");

  rlp_data->rbm.Initialised = FALSE;

  if (rlp_data->rbm.CurrPrim NEQ (T_RBM_PRIM *) NULL)
  {
    PFREE (rlp_data->rbm.CurrPrim)
    rlp_data->rbm.CurrPrim = (T_RBM_PRIM *) NULL;
  }

  while (rlp_data->rbm.PQ_Read NEQ rlp_data->rbm.PQ_Write)
  {
    if (rlp_data->rbm.PQ_Array[rlp_data->rbm.PQ_Read]
    NEQ (T_RBM_PRIM *) NULL)
    {
      PFREE (rlp_data->rbm.PQ_Array[rlp_data->rbm.PQ_Read])
      rlp_data->rbm.PQ_Array[rlp_data->rbm.PQ_Read]
       = (T_RBM_PRIM *) NULL;
    }
    rlp_data->rbm.PQ_Read = (rlp_data->rbm.PQ_Read+1) % RBM_PQ_SIZE;
  }

}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_reset
+------------------------------------------------------------------------------
|  Description : This function must be called once at startup before any
|                other procedures of the RBM is invoked. (Coldstart)
|
|
|  Parameters  : rlp_data_ptr -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_reset(T_RBM *rbm)
{
  TRACE_FUNCTION ("rbm_reset()");

  rbm->CurrPrim    = (T_RBM_PRIM *) NULL;
  rbm->CurrPrimCou = 0;
  rbm->K           = 0;
  rbm->FrameInRiBu = FALSE;
  rbm->FrameSize   = FRAME_SIZE_SHORT;
  rbm->PQ_Read     = 0;
  rbm->PQ_Write    = 0;
  rbm->Initialised = FALSE;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_reset_srej_slots
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_reset_srej_slots
            (
              void
            )
{
  T_RBM_BUFFER_INDEX n;

  TRACE_FUNCTION ("rbm_reset_srej_slots()");

  for (n = 0; n < RBM_BUF_SIZE; n++)
  {
    switch (rlp_data->rbm.Slot[n].R_State)
    {
      case RBM_WAIT:
      case RBM_SREJ:
        rlp_data->rbm.Slot[n].R_State = RBM_IDLE;
        return;

      default:
        break;
    }
  }
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_reset_all_r_states
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_reset_all_r_states
            (
              void
            )
{
  T_RBM_BUFFER_INDEX n;

  TRACE_FUNCTION ("rbm_reset_all_r_states()");

  for (n = 0; n < RBM_BUF_SIZE; n++)
    rlp_data->rbm.Slot[n].R_State = RBM_IDLE;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_check_slots_srej
+------------------------------------------------------------------------------
|  Description : Checks wheter a received slot is to be SREJted.
|                Returns RBM_INVALID: IDX if No SREJ pending
|                0..n       : Slot num to be SREJted
|
|  Parameters  : -
|
|
|  Return      : n                -
|                RBM_INVALID_IDX  -
+------------------------------------------------------------------------------
*/


GLOBAL T_RBM_BUFFER_EXTIDX rbm_check_slots_srej(void)
{
  T_RBM_BUFFER_INDEX n;

  TRACE_FUNCTION ("rbm_check_slots_srej()");

  n = rlp_data->rbm.VR;

  do
  {
    switch (rlp_data->rbm.Slot[n].R_State)
    {
      case RBM_IDLE:
        return RBM_INVALID_IDX;

      case RBM_SREJ:
        return n;

      default:
        n = (n+1) % RBM_BUF_SIZE;
        break;
    }
  }
  while (n NEQ rlp_data->rbm.VR);

  return RBM_INVALID_IDX;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_set_rslot_wait
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : slot -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_set_rslot_wait
            (
              T_RBM_BUFFER_INDEX slot
            )
{
  TRACE_FUNCTION ("rbm_set_rslot_wait()");

  rlp_data->rbm.Slot[slot].R_State = RBM_WAIT;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_set_rslot_wait2srej
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : slot -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_set_rslot_wait2srej
            (
              T_RBM_BUFFER_INDEX slot
            )
{
  TRACE_FUNCTION ("rbm_set_rslot_wait2srej()");

  rlp_data->rbm.Slot[slot].R_State = RBM_SREJ;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_set_rslot_rcvd
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : slot       -
|                resetTimer -
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_set_rslot_rcvd
            (
              T_RBM_BUFFER_EXTIDX  slot,
              BOOL               *resetTimer
            )
{
  TRACE_FUNCTION ("rbm_set_rslot_rcvd()");

  if(slot EQ RBM_INVALID_IDX)
    slot = rlp_data->rbm.LastVR;

  switch (rlp_data->rbm.Slot[slot].R_State)
  {
    case RBM_WAIT:
      *resetTimer = TRUE;
      break;

    default:
      *resetTimer = FALSE;
      break;
  }

  rlp_data->rbm.Slot[slot].R_State = RBM_RCVD;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_get_current_frame
+------------------------------------------------------------------------------
|  Description : This function returns the current - i.e. last stored -
|                frame of the receive buffer. The frame may be in the ring
|                buffer or in the static buffer.
|
|  Parameters  : -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL T_RBM_FRAMEPTR  rbm_get_current_frame
                       (
                         void
                       )
{

  T_RBM_FRAMEPTR frame;

  TRACE_FUNCTION ("rbm_get_current_frame()");

  if (rlp_data->rbm.FrameInRiBu)
    frame = rlp_data->rbm.Slot[rlp_data->rbm.VR].Frame;
  else
    frame = rlp_data->rbm.Frame;

  return frame;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_accept_current_frame
+------------------------------------------------------------------------------
|  Description : This function advances VR to make sure, that the next
|                frame is stored in the next free slot.
|
|  Parameters  : -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_accept_current_frame
            (
              void
            )
{
  TRACE_FUNCTION ("rbm_accept_current_frame()");

  rlp_data->rbm.LastVR = rlp_data->rbm.VR;

  do
  {
    rlp_data->rbm.VR = (rlp_data->rbm.VR +1) % RBM_BUF_SIZE;
  } while (rlp_data->rbm.Slot[rlp_data->rbm.VR].R_State EQ RBM_RCVD);
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_mark_missing_i_frames_srej
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : ns -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_mark_missing_i_frames_srej
            (
              T_RBM_BUFFER_INDEX ns
            )
{
  T_RBM_BUFFER_INDEX n;

  TRACE_FUNCTION ("rbm_mark_missing_i_frames_srej()");

  n = rlp_data->rbm.VR;

  do
  {
    switch (rlp_data->rbm.Slot[n].R_State)
    {
      case RBM_IDLE:
        rlp_data->rbm.Slot[n].R_State = RBM_SREJ;
        break;

      default:
        break;
    }

    n = (n+1) % RBM_BUF_SIZE;
  }
  while (n NEQ ns);
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_count_missing_i_frames
+------------------------------------------------------------------------------
|  Description : Counts all slots in R buffer, which will be marked by
|                rbm_mark_missing_i_frames_srej
|
|  Parameters  : ns     -
|                count  -
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_count_missing_i_frames
            (
              T_RBM_BUFFER_INDEX  ns,
              T_RBM_BUFFER_INDEX *count
            )
{
  T_RBM_BUFFER_INDEX n;

  TRACE_FUNCTION ("rbm_count_missing_i_frames()");

  *count = 0;
  n      = rlp_data->rbm.VR;

  do
  {
    switch (rlp_data->rbm.Slot[n].R_State)
    {
      case RBM_IDLE:
        (*count)++;
        break;

      default:
        break;
    }

    n = (n+1) % RBM_BUF_SIZE;
  }
  while (n NEQ ns);
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_buffer_all_in_sequence_frames
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : fromSlot     -
|                primIsReady  -
|                rcvReady     -
|                rcvFull      -
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_buffer_all_in_sequence_frames
            (
              T_RBM_BUFFER_EXTIDX   fromSlot,
              BOOL                 *primIsReady,
              BOOL                 *rcvReady,
              BOOL                 *rcvFull
            )
{
  TRACE_FUNCTION ("rbm_buffer_all_in_sequence_frames()");

  if(fromSlot EQ RBM_INVALID_IDX)
    fromSlot = rlp_data->rbm.LastVR;

  *primIsReady = FALSE;

  do
  {
    rbmi_buffer_frame (fromSlot, primIsReady);
    rlp_data->rbm.Slot[fromSlot].R_State = RBM_IDLE;
    fromSlot = (fromSlot + 1) % RBM_BUF_SIZE;
  } while (rlp_data->rbm.Slot[fromSlot].R_State EQ RBM_RCVD);

  rbmi_pq_check (rcvReady, rcvFull);
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_ns_check
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : ns       -
|                valid    -
|                expected -
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rbm_ns_check
            (
              T_RBM_BUFFER_INDEX  ns,
              BOOL               *valid,
              BOOL               *expected
            )
{
  USHORT max_ns;

  TRACE_FUNCTION ("rbm_ns_check()");

  if(rlp_data->rbm.K EQ 0)
  {
    *valid    = FALSE;
    *expected = FALSE;
    return;
  }


  max_ns = (rlp_data->rbm.VR + rlp_data->rbm.K -1) % RBM_BUF_SIZE;
  /*
   * ns within Window?
   */
  if (!(XOR
        (
          XOR
          (
            rlp_data->rbm.VR > ns,
            ns > max_ns
          ),
          rlp_data->rbm.VR > max_ns
        )
       )
     )
  {
    *valid    = TRUE;
    *expected = (ns EQ rlp_data->rbm.VR);
  }
  else
  {
    *valid    = FALSE;
    *expected = FALSE;
  }
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_get_vr
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : -
|
|
|  Return      : VR
+------------------------------------------------------------------------------
*/


GLOBAL T_RBM_BUFFER_INDEX rbm_get_vr
                          (
                            void
                          )
{
  TRACE_FUNCTION ("rbm_get_vr()");

  return rlp_data->rbm.VR;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_get_prim
+------------------------------------------------------------------------------
|  Description : This is just a wrapper for rbmi_pq_deq. The queu is an
|                internal matter of the RBM, therefore the function
|                rbmi_pq_deq should not be used directly by the user.
|
|  Parameters  : prim     -
|                rcvReady -
|                rcvFull  -
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL BOOL rbm_get_prim
            (
              T_RBM_PRIM **prim,
              BOOL       *rcvReady,
              BOOL       *rcvFull
            )
{
  BOOL primFound;
  TRACE_FUNCTION ("rbm_get_prim()");

  primFound = rbmi_pq_deq (prim);
  if (primFound)
  {
    rbmi_pq_check(rcvReady, rcvFull);
  }
  return primFound;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_get_curr_prim
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : -
|
|
|  Return      : prim
+------------------------------------------------------------------------------
*/


GLOBAL T_RBM_PRIM *rbm_get_curr_prim
            (
              void
            )
{
  T_RBM_PRIM *prim;

  TRACE_FUNCTION ("rbm_get_curr_prim()");

  rlp_data->rbm.CurrPrim->sdu.l_buf
    = rlp_data->rbm.CurrPrimCou * rlp_data->rbm.FrameSize * 8;

  rlp_data->rbm.CurrPrim->sdu.o_buf  = 0;

  prim = rlp_data->rbm.CurrPrim;

  rbmi_alloc_curr_prim ();

  return prim;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_move_current_frame
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  :
|
|
|  Return      :
+------------------------------------------------------------------------------
*/



GLOBAL void rbm_move_current_frame
            (
              T_RBM_BUFFER_INDEX slot
            )
{
  TRACE_FUNCTION ("rbm_move_current_frame()");

  memcpy
  (
    rlp_data->rbm.Slot[slot].Frame,
    rlp_data->rbm.Slot[rlp_data->rbm.VR].Frame,
    rlp_data->rbm.FrameSize
  );
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_is_state_wait
+------------------------------------------------------------------------------
|  Description : This function is called from the HISR. It returns the
|                frame descriptor for the buffer, in which the HISR has to
|                write the received frame.
|
|
|  Parameters  : slot -
|
|
|  Return      : TRUE  -
|                FALSE -
+------------------------------------------------------------------------------
*/


GLOBAL BOOL rbm_is_state_wait
            (
              T_RBM_BUFFER_INDEX slot
            )
{
  TRACE_FUNCTION ("rbm_is_state_wait()");

  if (rlp_data->rbm.Slot[slot].R_State EQ RBM_WAIT)
    return TRUE;
  else
    return FALSE;
}

/*
+------------------------------------------------------------------------------
|  Function    : rbm_prepare_remap
+------------------------------------------------------------------------------
|  Description :
|
|  Parameters  : frameSize -
|
|
|  Return      :
+------------------------------------------------------------------------------
*/


GLOBAL T_FRAME_NUM rbm_prepare_remap
                   (
                     USHORT frameSize
                   )
{
  T_RBM_PRIM *prim;
  USHORT oldFrameSize;
  USHORT currPrimCou;

  TRACE_FUNCTION ("rbm_prepare_remap()");

  oldFrameSize = rlp_data->rbm.FrameSize;
  currPrimCou  = rlp_data->rbm.CurrPrimCou;

  rlp_data->rbm.FrameSize = frameSize;

  prim = rbm_get_curr_prim ();

  prim->sdu.l_buf = currPrimCou * oldFrameSize * 8;

  rbmi_pq_enq (prim);

  return (rbm_get_vr());
}

#ifdef _SIMULATION_
/*
+------------------------------------------------------------------------------
|  Function    : rbm_store_frame
+------------------------------------------------------------------------------
|  Description : This procedure is only used in the simulation environment
|                to store a frame in the receive buffer. 
|                In the implementation the copy is performed 
|                by the RA adaptation layer
|                which has access to the shared memory area of the DSP.
|
|  Parameters  : frame -
|
|  Return      : -
+------------------------------------------------------------------------------
*/

GLOBAL void rbm_store_frame(T_RBM_FRAMEPTR frame)
{
  TRACE_FUNCTION ("rbm_store_frame()");

  if (rlp_data->rbm.Initialised)
  {
    memcpy
    (
      rlp_data->rbm.Slot[rlp_data->rbm.VR].Frame,
      frame,
      rlp_data->rbm.FrameSize
    );

    rlp_data->rbm.FrameInRiBu = TRUE;
  }
  else
  {
    memcpy
    (
      rlp_data->rbm.Frame,
      frame,
      rlp_data->rbm.FrameSize
    );

    rlp_data->rbm.FrameInRiBu = FALSE;
  }
}
#endif

#ifdef _TARGET_
/*
+------------------------------------------------------------------------------
|  Function    : rlp_rbm_get_next_buffer
+------------------------------------------------------------------------------
|  Description : This function is called from the HISR. It returns the
|                frame descriptor for the buffer, in which the HISR has to
|                write the received frame.
|
|
|  Parameters  : frameDesc -
|
|
|  Return      : -
+------------------------------------------------------------------------------
*/


GLOBAL void rlp_rbm_get_next_buffer(T_FRAME_DESC *frameDesc)
{
  TRACE_FUNCTION ("rbm_get_next_buffer()");

  if (rlp_data->rbm.Initialised)
  {
    frameDesc->Adr[0] = rlp_data->rbm.Slot[rlp_data->rbm.VR].Frame;
    rlp_data->rbm.FrameInRiBu = TRUE;
  }
  else
  {
    frameDesc->Adr[0] = rlp_data->rbm.Frame;
    rlp_data->rbm.FrameInRiBu = FALSE;
  }

  frameDesc->Len[0] = rlp_data->rbm.FrameSize;
  frameDesc->Adr[1] = (UBYTE *) NULL;
  frameDesc->Len[1] = 0;
}
#endif