view src/g23m-gprs/llc/llc_irxs.c @ 62:089c1882788c

AT%CBC extended to report Ichg
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 22 Oct 2020 22:37:31 +0000
parents fa8dc04885d8
children
line wrap: on
line source

/* 
+----------------------------------------------------------------------------- 
|  Project :  
|  Modul   :  
+----------------------------------------------------------------------------- 
|  Copyright 2002 Texas Instruments Berlin, AG 
|                 All rights reserved. 
| 
|                 This file is confidential and a trade secret of Texas 
|                 Instruments Berlin, AG 
|                 The receipt of or possession of this file does not convey 
|                 any rights to reproduce or disclose its contents or to 
|                 manufacture, use, or sell anything it may describe, in 
|                 whole, or in part, without the specific written consent of 
|                 Texas Instruments Berlin, AG. 
+----------------------------------------------------------------------------- 
|  Purpose :  This modul is part of the entity LLC and implements all 
|             functions to handles the incoming process internal signals as  
|             described in the SDL-documentation (IRX-statemachine)
+----------------------------------------------------------------------------- 
*/ 

#ifndef LLC_IRXS_C
#define LLC_IRXS_C
#endif

#define ENTITY_LLC

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

#include "typedefs.h"   /* to get Condat data types */
#include "vsi.h"        /* to get a lot of macros */
#include "macdef.h"
#include "gprs.h"
#include "gsm.h"        /* to get a lot of macros */
#include "cnf_llc.h"    /* to get cnf-definitions */
#include "mon_llc.h"    /* to get mon-definitions */
#include "prim.h"       /* to get the definitions of used SAP and directions */
#include "llc.h"        /* to get the global entity definitions */

#include "llc_irxf.h"    /* to get IRX helper functions */
#include "llc_irxl.h"    /* to get IRX label functions */
#include "llc_itxs.h"    /* to get IRX/ITX signals */
#include "llc_us.h"      /* to get U signals */


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

/*==== LOCAL VARS ===========================================================*/

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

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



/*
+------------------------------------------------------------------------------
| Function    : sig_llme_irx_assign_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_LLME_IRX_ASSIGN_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_llme_irx_assign_req (void)
{ 
  TRACE_ISIG( "sig_llme_irx_assign_req" );
  
  switch (GET_STATE(IRX))
  {
    case IRX_TLLI_UNASSIGNED:
      /*
       * Initialise current incarnation.
       */
      irx_init_sapi();
      SET_STATE (IRX, IRX_TLLI_ASSIGNED);
      break;

    default:
      TRACE_ERROR( "SIG_LLME_IRX_ASSIGN_REQ unexpected" );
      break;
  }
} /* sig_llme_irx_assign_req() */


/*
+------------------------------------------------------------------------------
| Function    : sig_llme_irx_unassign_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_LLME_IRX_UNASSIGN_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_llme_irx_unassign_req (void)
{ 
  TRACE_ISIG( "sig_llme_irx_unassign_req" );
  
  switch (GET_STATE(IRX))
  {
    case IRX_TLLI_UNASSIGNED:
      /*
       * Ignore unexpected signal
       */
      break;

    default:
      /*
       * Delete stored I frames and change to state TLLI_UNASSIGNED
       */
      irx_queue_clean();
      irx_init_sapi();
      SET_STATE (IRX, IRX_TLLI_UNASSIGNED);
      break;
  }
} /* sig_llme_irx_unassign_req() */


/*
+------------------------------------------------------------------------------
| Function    : sig_llme_irx_reset_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_LLME_IRX_RESET_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_llme_irx_reset_req (void)
{ 
  TRACE_ISIG( "sig_llme_irx_reset_req" );

 
  switch (GET_STATE(IRX))
  {
    case IRX_TLLI_UNASSIGNED:
    case IRX_TLLI_ASSIGNED:
      /*
       * Ignore signal.
       */
      break;

    case IRX_ABM:
    case IRX_ABM_BUSY:
      /*
       * Delete stored I frames and change to state TLLI_UNASSIGNED
       */
      irx_queue_clean();
      irx_init_sapi();
      SET_STATE (IRX, IRX_TLLI_ASSIGNED);
      break;

    default:
      TRACE_ERROR( "SIG_LLME_IRX_RESET_REQ unexpected" );
      break;
  }
} /* sig_llme_irx_reset_req() */



/*
+------------------------------------------------------------------------------
| Function    : sig_llme_irx_abmest_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_LLME_IRX_ABMEST_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_llme_irx_abmest_req (void)
{ 
  TRACE_ISIG( "sig_llme_irx_abmest_req" );

  switch (GET_STATE(IRX))
  {
    case IRX_TLLI_ASSIGNED:
      /*
       * Initialize ABM operation
       */
      irx_init_abm();
      SET_STATE (IRX, IRX_ABM);
      break;

    case IRX_ABM:
    case IRX_ABM_BUSY:
      /*
       * Delete stored I frames and re-initialize ABM operation
       */
      irx_queue_clean();
      irx_init_abm();
      SET_STATE (IRX, IRX_ABM);
      break;

    default:
      TRACE_ERROR( "SIG_LLME_IRX_ABMEST_REQ unexpected" );
      break;
  }
} /* sig_llme_irx_abmest_req() */



/*
+------------------------------------------------------------------------------
| Function    : sig_llme_irx_abmrel_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_LLME_IRX_ABMREL_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_llme_irx_abmrel_req (void)
{ 
  TRACE_ISIG( "sig_llme_irx_abmrel_req" );
 
  switch (GET_STATE(IRX))
  {
    case IRX_ABM:
    case IRX_ABM_BUSY:
      /*
       * Delete stored I frames and end ABM operation
       */
      irx_queue_clean();
      irx_init_sapi();
      SET_STATE (IRX, IRX_TLLI_ASSIGNED);
      break;

    default:
      /* TRACE_ERROR( "SIG_LLME_IRX_ABMREL_REQ unexpected" ); but ok */
      break;
  }
} /* sig_llme_irx_abmrel_req() */



/*
+------------------------------------------------------------------------------
| Function    : sig_rx_irx_data_ind
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_RX_IRX_DATA_IND
|
| Parameters  : ll_unitdata_ind - a valid pointer to an LL-UNITDATA-IND 
|                                 primitive
|               command    - contains the command within the primitive
|               frame_type - type of PDU (I or S frame)
|               cr_bit     - setting of the CR bit
|               a_bit      - setting of the A bit
|               ns         - send sequence number of the frame 
|               nr         - receive sequence number of the frame
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_rx_irx_data_ind (T_LL_UNITDATA_IND *ll_unitdata_ind,
                                 T_COMMAND         command, 
                                 T_PDU_TYPE        frame_type,
                                 T_BIT             cr_bit,
                                 T_BIT             a_bit,
                                 T_FRAME_NUM       ns, 
                                 T_FRAME_NUM       nr)
{
  UBYTE     state;

  TRACE_ISIG( "sig_rx_irx_data_ind" );
  
#ifdef TRACE_EVE
    {
      static char* sf[] = { "RR", "ACK", "RNR", "SACK" };

      if(command <= 3)
      {
        if(frame_type == I_FRAME)
        {
          TRACE_4_INFO("got %s I-Frame NS:%d NR:%d A:%d", sf[command], ns, nr, a_bit);
        }
        else
        {
          TRACE_3_INFO("got %s S-Frame NR:%d A:%d", sf[command], nr, a_bit);
        }
      }
    }
#endif

  llc_data->u->current_tlli = ll_unitdata_ind->tlli;

  switch ( (state = GET_STATE(IRX)) )
  {
    case IRX_TLLI_ASSIGNED:
      /*
       * Send a DM response to any valid command received, that 
       * cannot be handeled (GSM 4.64 Release 6.7.0 Chapter 6.4.1.4)
       */
      TRACE_0_INFO("S- or I/S-Frame received in unexpected state");
      
      PFREE (ll_unitdata_ind);

      sig_irx_u_no_frame_expected_ind();
      break;

    case IRX_ABM:
    case IRX_ABM_BUSY:
      /*
       * va <= nr <= vs 
       */
      if ( FRAME_NUM_VALID (llc_data->sapi->va, nr, llc_data->sapi->vs) )
      {
        /*
         * frame valid
         */
        irx_ack_all_to ((T_FRAME_NUM)(nr - 1));

        switch (command)
        {
          case I_RR:
            /*
             * Label IRX_RR
             */
            sig_irx_itx_peer_ready_ind();
            break;

          case I_ACK:
            /*
             * Label IRX_ACK
             */
            sig_irx_itx_ack_ind (FALSE, nr );
            sig_irx_itx_ack_ind (TRUE, (T_FRAME_NUM)(nr + 1));
            sig_irx_itx_cnf_l3data_req ();
            sig_irx_itx_peer_ready_ind ();
            break;

          case I_SACK:
            /*
             * Label IRX_SACK
             */
            sig_irx_itx_ack_ind (FALSE, nr);
            irx_handle_sack (nr, ll_unitdata_ind, frame_type);
            sig_irx_itx_peer_ready_ind();
            break;

          case I_RNR:
            /*
             * Label IRX_RNR
             */
            sig_irx_itx_peer_busy_ind();
            break;

          default:
            TRACE_ERROR( "Unexpected command received" );
            break;
        }
      }
         
      if (frame_type == I_FRAME)
      {
        irx_label_if (ll_unitdata_ind, ns, a_bit, state);
      }
      else /*  S_FRAME */
      {
        if (state == IRX_ABM)
        {
          irx_send_ack (a_bit);
          PFREE (ll_unitdata_ind);
        }
        else
        {
          irx_send_rnr ();
          PFREE (ll_unitdata_ind);
        }
      }
      break;

    default:
      /*
       * Free unexpected data
       */
      PFREE (ll_unitdata_ind);
      TRACE_ERROR( "SIG_RX_IRX_DATA_IND unexpected" );
      break;
  }
} /* sig_rx_irx_data_ind() */



/*
+------------------------------------------------------------------------------
| Function    : sig_itx_irx_s_frame_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_ITX_IRX_S_FRAME_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_itx_irx_s_frame_req (T_ABIT_REQ_TYPE req)
{ 
  TRACE_ISIG( "sig_itx_irx_s_frame_req" );
  
  switch (GET_STATE(IRX))
  {
    case IRX_ABM:
      /*
       * Send an S frame appropriate for the current state
       */
      if ( llc_data->irx->last_ns == NS_EQUAL_VR )
      {
        sig_irx_itx_send_rr_req (req);
      }
      else if ( llc_data->irx->last_ns == NS_EQUAL_VR_PLUS_1 )
      {
        sig_irx_itx_send_ack_req (req);
      }
      else
      {
        T_SACK_BITMAP bitmap;

        irx_build_sack_bitmap( &bitmap );
        sig_irx_itx_send_sack_req (req, &bitmap);
      }
      /* SET_STATE (IRX, SAME_STATE); */
      break;
  

    case IRX_ABM_BUSY:
      /*
       * The appropriate S frame in state busy anytime is an RNR
       */
      sig_irx_itx_send_rnr_req (req);
      /* SET_STATE (IRX, SAME_STATE); */
      break;

    default:
      TRACE_ERROR( "SIG_ITX_IRX_S_FRAME_REQ unexpected" );
      break;
  }
} /* sig_itx_irx_s_frame_req() */