view src/g23m-gprs/llc/llc_itxs.c @ 183:219afcfc6250

src/g23m-gprs: initial import from TCS3.2/LoCosto
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 13 Oct 2016 04:24:13 +0000
parents
children
line wrap: on
line 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 (ITX-statemachine)
+----------------------------------------------------------------------------- 
*/ 

#ifndef LLC_ITXS_C
#define LLC_ITXS_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_itxs.h"   /* to get ITX signal definitions */
#include "llc_itxf.h"   /* to get ITX function definitions */
#include "llc_itxt.h"   /* to get ITX T201 function definitions */

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

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

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

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


/*
+------------------------------------------------------------------------------
| Function    : sig_llme_itx_assign_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_LLME_ITX_ASSIGN_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_llme_itx_assign_req (void)
{ 
  TRACE_ISIG( "sig_llme_itx_assign_req" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_TLLI_UNASSIGNED:
      /*
       * Init Sapi
       */
      itx_init_sapi();
      SET_STATE (ITX, ITX_TLLI_ASSIGNED);
      break;

    default:
      TRACE_ERROR( "SIG_LLME_ITX_ASSIGN_REQ unexpected" );
      break;
  }
} /* sig_llme_itx_assign_req() */


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

  switch (GET_STATE(ITX))
  {
    case ITX_TLLI_UNASSIGNED:
      /*
       * Ignore unexpected signal.
       */
      break;

    default:
      TIMERSTOP (T201);
      itx_s_queue_clean ();
      itx_i_queue_clean ();
      itx_init_sapi ();
      SET_STATE (ITX, ITX_TLLI_UNASSIGNED);
      break;
  }
} /* sig_llme_itx_unassign_req() */


/*
+------------------------------------------------------------------------------
| Function    : sig_llme_itx_reset_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_LLME_ITX_RESET_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_llme_itx_reset_req (void) 
{ 
  TRACE_ISIG( "sig_llme_itx_reset_req" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_TLLI_UNASSIGNED:
    case ITX_TLLI_ASSIGNED:
      /*
       * nothing to do
       */
      break;

    case ITX_ABM:
    case ITX_ABM_PEER_BUSY:
      TIMERSTOP (T201);
      itx_s_queue_clean ();
      itx_i_queue_clean ();
      itx_init_sapi ();
      SET_STATE (ITX, ITX_TLLI_ASSIGNED);
      break;

    default:
      TRACE_ERROR( "SIG_LLME_ITX_RESET_REQ unexpected" );
      break;
  }
} /* sig_llme_itx_reset_req() */


/*
+------------------------------------------------------------------------------
| Function    : sig_llme_itx_abmest_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_LLME_ITX_ABMEST_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_llme_itx_abmest_req (void) 
{ 
  TRACE_ISIG( "sig_llme_itx_abmest_req" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_TLLI_UNASSIGNED:
      /*
       * Ignore unexpected signal.
       */
      TRACE_ERROR( "SIG_LLME_ITX_ABMEST_REQ unexpected" );
      break;

    default:
      TIMERSTOP (T201);
      itx_s_queue_clean ();
      itx_i_queue_clean ();
      itx_init_sapi ();
      itx_handle_ll_ready_ind (FALSE);
      SET_STATE (ITX, ITX_ABM);
      TRACE_1_INFO("ABM established s:%d", llc_data->current_sapi);
      break;
  }
} /* sig_llme_itx_abmest_req() */


/*
+------------------------------------------------------------------------------
| Function    : sig_llme_itx_abmrel_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_LLME_ITX_ABMREL_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_llme_itx_abmrel_req (void) 
{ 
  TRACE_ISIG( "sig_llme_itx_abmrel_req" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_TLLI_UNASSIGNED:
      /*
       * Ignore unexpected signal.
       */
      TRACE_ERROR( "SIG_LLME_ITX_ABMREL_REQ unexpected" );
      break;

    default:
      TIMERSTOP (T201);
      itx_s_queue_clean ();
      itx_i_queue_clean ();
      itx_init_sapi ();
      SET_STATE (ITX, ITX_TLLI_ASSIGNED);
      TRACE_1_INFO("ABM released s:%d", llc_data->current_sapi);
      break;
  }
} /* sig_llme_itx_abmrel_req() */



/*
+------------------------------------------------------------------------------
| Function    : sig_llme_itx_suspend_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_LLME_ITX_SUSPEND_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_llme_itx_suspend_req (void) 
{ 
  TRACE_ISIG( "sig_llme_itx_suspend_req" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_TLLI_UNASSIGNED:
    case ITX_TLLI_ASSIGNED:
      /*
       * nothing to do
       */
      break;

    case ITX_ABM:
    case ITX_ABM_PEER_BUSY:
      /*
       * Reset T201, but do NOT reset t201_entry pointer
       * because we have to restart T201 later!
       */
      TIMERSTOP (T201);
      /* SET_STATE (ITX, SAME_STATE); */
      break;

    default:
      TRACE_ERROR( "SIG_LLME_ITX_SUSPEND_REQ unexpected" );
      break;
  }
} /* sig_llme_itx_suspend_req() */


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

  switch (GET_STATE(ITX))
  {
    case ITX_TLLI_UNASSIGNED:
    case ITX_TLLI_ASSIGNED:
      /*
       * nothing to do
       */
      break;

    case ITX_ABM:
      /*
       * Restart T201 if a frame was associated to it.
       * Do not increment frame retransmission counter.
       */
      if ( llc_data->itx->t201_entry != NULL )
      {
        TIMERSTART (T201, llc_data->t200->length);
      }

      /*
       * Continue sending of frames
       */
      itx_send_next_frame (ABIT_NO_REQ);
      break;

    case ITX_ABM_PEER_BUSY:
      /*
       * Restart T201, but do not increment counter
       */
      TIMERSTART (T201, llc_data->t200->length);
      break;

    default:
      TRACE_ERROR( "SIG_LLME_ITX_RESUME_REQ unexpected" );
      break;
  }
} /* sig_llme_itx_resume_req() */




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

  switch (GET_STATE(ITX))
  {
    case ITX_TLLI_ASSIGNED:
      llc_data->itx->tx_waiting = TRUE;
      /* SET_STATE (ITX, SAME_STATE); */
      break;

    case ITX_ABM:
    case ITX_ABM_PEER_BUSY:
      llc_data->itx->tx_waiting = TRUE;
      itx_send_next_frame (ABIT_NO_REQ);
      /* SET_STATE (ITX, SAME_STATE); */
      break;

    default:
      TRACE_ERROR( "SIG_TX_ITX_READY_IND unexpected" );
      break;
  }
} /* sig_tx_itx_ready_ind() */



/*
+------------------------------------------------------------------------------
| Function    : sig_irx_itx_ack_ind
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_IRX_ITX_ACK_IND
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_irx_itx_ack_ind (BOOL is_ack, T_FRAME_NUM num) 
{ 
  TRACE_ISIG( "sig_irx_itx_ack_ind" );
  
  num %= (MAX_SEQUENCE_NUMBER+1);

#ifdef TRACE_EVE
  {
    if (is_ack == TRUE)
    {
      TRACE_1_INFO("got frame ack:%d", num);
    }
    else
    {
      TRACE_1_INFO("got frame request:%d", num);
    }
  }
#endif

  switch (GET_STATE(ITX))
  {
    case ITX_ABM:
    case ITX_ABM_PEER_BUSY:
      /*
       * Set frame acknowledge status in the ITX queue.
       */
      if (is_ack)
        itx_i_queue_set_status (IQ_IS_ACK_FRAME, num);
      else
        itx_i_queue_set_status (IQ_RETR_FRAME, num);

      /* SET_STATE (ITX, SAME_STATE); */
      break;

    default:
      TRACE_ERROR( "SIG_IRX_ITX_ACK_IND unexpected" );
      break;
  }
} /* sig_irx_itx_ack_ind() */



/*
+------------------------------------------------------------------------------
| Function    : sig_irx_itx_cnf_l3data_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_IRX_ITX_CNF_L3DATA_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_irx_itx_cnf_l3data_req (void) 
{ 
  UBYTE           state;
  BOOL            found;
  BOOL            data_retrieved = FALSE;
#ifdef LL_2to1
  T_LL_reference1    reference;
#else
  T_reference1    reference;
#endif

  TRACE_ISIG( "sig_irx_itx_cnf_l3data_req" );
  
  state = GET_STATE(ITX);
  
  switch (state)
  {
    case ITX_ABM:
    case ITX_ABM_PEER_BUSY:
      /*
       * Get all acknowledged frames from the ITX queue.
       * If one or more are found, send an LL_DATA_CNF 
       * for each group of max LL_MAX_CNF L3-PDUs.
       */
      itx_i_queue_get_ready (&found, &reference, state);
      data_retrieved = found;

      /*
       * Label LLC_ACK_IND
       */

      while (found)
      {
        int num_ref = 0;

        PALLOC (ll_data_cnf, LL_DATA_CNF);

        ll_data_cnf->sapi = llc_data->current_sapi;

        do {

          ll_data_cnf->reference1[num_ref] = reference;
          num_ref++;

          itx_i_queue_get_ready (&found, &reference, state);

        } while (found && (num_ref < LLC_MAX_CNF));

        ll_data_cnf->c_reference1 = num_ref;

        TRACE_1_OUT_PARA("s:%d", ll_data_cnf->sapi );
        PSEND (hCommSNDCP, ll_data_cnf);
      }

      /*
       * If we have taken data from queue, check 
       * if a L3 ready indication is required
       */
      if (data_retrieved)
      {
        itx_handle_ll_ready_ind (data_retrieved);
      }

      /* SET_STATE (ITX, SAME_STATE); */
      break;

    default:
      TRACE_ERROR( "SIG_IRX_ITX_CNF_L3DATA_REQ unexpected" );
      break;
  }
} /* sig_irx_itx_cnf_l3data_req() */


/*
+------------------------------------------------------------------------------
| Function    : sig_irx_itx_trigger_ind
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_IRX_ITX_TRIGGER_IND
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_irx_itx_trigger_ind (void) 
{ 
  TRACE_ISIG( "sig_irx_itx_trigger_ind" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_ABM:
    case ITX_ABM_PEER_BUSY:
      itx_send_next_frame (ABIT_NO_REQ);
      /* SET_STATE (ITX, SAME_STATE); */
      break;

    default:
      TRACE_ERROR( "SIG_IRX_ITX_TRIGGER_IND unexpected" );
      break;
  }
} /* sig_irx_itx_trigger_ind() */


/*
+------------------------------------------------------------------------------
| Function    : sig_irx_itx_peer_busy_ind
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_IRX_ITX_PEER_BUSY_IND
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_irx_itx_peer_busy_ind (void) 
{ 
  TRACE_ISIG( "sig_irx_itx_peer_busy_ind" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_ABM:
      /*
       * Start T201 to supervise peer busy condition,
       * init T201 peer busy restart counter and change 
       * into peer busy state.
       */
      TIMERSTART (T201, llc_data->t200->length);
      llc_data->itx->n_pb_retr = 0;
      SET_STATE (ITX, ITX_ABM_PEER_BUSY);
      TRACE_1_INFO("Peer Busy s:%d", llc_data->current_sapi);
      break;

    case ITX_ABM_PEER_BUSY:
      /*
       * Restart T201 to supervise peer busy condition,
       * reset T201 peer busy restart counter.
       */
      TIMERSTART (T201, llc_data->t200->length);
      llc_data->itx->n_pb_retr = 0;
      break;

    default:
      TRACE_ERROR( "SIG_IRX_ITX_PEER_BUSY_IND unexpected" );
      break;
  }
} /* sig_irx_itx_peer_busy_ind() */



/*
+------------------------------------------------------------------------------
| Function    : sig_irx_itx_peer_ready_ind
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_IRX_ITX_PEER_READY_IND
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_irx_itx_peer_ready_ind (void) 
{ 
  TRACE_ISIG( "sig_irx_itx_peer_ready_ind" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_ABM:
      /*
       * ignore it
       */
      break;

    case ITX_ABM_PEER_BUSY:
      /*
       * Clear peer busy condition
       */
      SET_STATE (ITX, ITX_ABM);

      /*
       * Restart T201 if a frame was associated to it.
       * Do not increment frame retransmission counter.
       */
      if ( llc_data->itx->t201_entry != NULL )
      {
        TIMERSTART (T201, llc_data->t200->length);
      }

      /*
       * Restart sending of frames
       */
      TRACE_1_INFO("Peer Ready s:%d", llc_data->current_sapi);
      itx_send_next_frame (ABIT_NO_REQ);
      break;

    default:
      TRACE_ERROR( "SIG_IRX_ITX_PEER_READY_IND unexpected" );
      break;
  }
} /* sig_irx_itx_peer_ready_ind() */



/*
+------------------------------------------------------------------------------
| Function    : sig_irx_itx_send_rr_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_IRX_ITX_SEND_RR_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_irx_itx_send_rr_req (T_ABIT_REQ_TYPE req_type)
{ 
  TRACE_ISIG( "sig_irx_itx_send_rr_req" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_ABM:
    case ITX_ABM_PEER_BUSY:
      itx_s_queue_store (I_RR, req_type, llc_data->sapi->vr, NULL);
      itx_send_next_frame (ABIT_NO_REQ);
      /* SET_STATE (ITX, SAME_STATE); */
      break;

    default:
      TRACE_ERROR( "SIG_IRX_ITX_SEND_RR_REQ unexpected" );
      break;
  }
} /* sig_irx_itx_send_rr_req() */


/*
+------------------------------------------------------------------------------
| Function    : sig_irx_itx_send_ack_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_IRX_ITX_SEND_ACK_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_irx_itx_send_ack_req (T_ABIT_REQ_TYPE req_type)
{ 
  TRACE_ISIG( "sig_irx_itx_send_ack_req" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_ABM:
    case ITX_ABM_PEER_BUSY:
      itx_s_queue_store (I_ACK, req_type, llc_data->sapi->vr, NULL);
      itx_send_next_frame (ABIT_NO_REQ);
      /* SET_STATE (ITX, SAME_STATE); */
      break;

    default:
      TRACE_ERROR( "SIG_IRX_ITX_SEND_ACK_REQ unexpected" );
      break;
  }
} /* sig_irx_itx_send_ack_req() */



/*
+------------------------------------------------------------------------------
| Function    : sig_irx_itx_send_sack_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_IRX_ITX_SEND_SACK_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_irx_itx_send_sack_req (T_ABIT_REQ_TYPE req_type, T_SACK_BITMAP* bitmap)
{ 
  TRACE_ISIG( "sig_irx_itx_send_sack_req" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_ABM:
    case ITX_ABM_PEER_BUSY:
      itx_s_queue_store (I_SACK, req_type, llc_data->sapi->vr, bitmap);
      itx_send_next_frame (ABIT_NO_REQ);
      /* SET_STATE (ITX, SAME_STATE); */
      break;

    default:
      TRACE_ERROR( "SIG_IRX_ITX_SEND_SACK_REQ unexpected" );
      break;
  }
} /* sig_irx_itx_send_sack_req() */




/*
+------------------------------------------------------------------------------
| Function    : sig_irx_itx_send_rnr_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_IRX_ITX_SEND_RNR_REQ
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_irx_itx_send_rnr_req (T_ABIT_REQ_TYPE req_type)
{ 
  TRACE_ISIG( "sig_irx_itx_send_rnr_req" );
  
  switch (GET_STATE(ITX))
  {
    case ITX_ABM:
    case ITX_ABM_PEER_BUSY:
      itx_s_queue_store (I_RNR, req_type, llc_data->sapi->vr, NULL);
      itx_send_next_frame (ABIT_NO_REQ);
      /* SET_STATE (ITX, SAME_STATE); */
      break;

    default:
      TRACE_ERROR( "SIG_IRX_ITX_SEND_RNR_REQ unexpected" );
      break;
  }
} /* sig_irx_itx_send_rnr_req() */