diff src/g23m-gprs/sndcp/sndcp_sdas.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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/g23m-gprs/sndcp/sndcp_sdas.c	Thu Oct 13 04:24:13 2016 +0000
@@ -0,0 +1,596 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  GPRS (8441)
+|  Modul   :  sndcp_sdas.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 is part of the entity SNDCP and implements all 
+|             functions to handles the incoming process internal signals as  
+|             described in the SDL-documentation (SD-statemachine)
++----------------------------------------------------------------------------- 
+*/ 
+
+
+#define ENTITY_SNDCP
+
+/*==== INCLUDES =============================================================*/
+
+#include "typedefs.h"    /* to get Condat data types */
+#include "vsi.h"        /* to get a lot of macros */
+#include "macdef.h"
+#include "gsm.h"        /* to get a lot of macros */
+#include "prim.h"       /* to get the definitions of used SAP and directions */
+
+#include "dti.h"
+#include "sndcp.h"        /* to get the global entity definitions */
+#include "sndcp_f.h"       /* to get the functions to access the global arrays*/
+
+#include "sndcp_sdaf.h"    /* to get the internal functions of this service */
+#include "sndcp_nds.h"    /* to get signals to nd service */
+
+
+/*==== CONST ================================================================*/
+
+/*==== LOCAL VARS ===========================================================*/
+
+/*==== PRIVATE FUNCTIONS ====================================================*/
+
+/*==== PUBLIC FUNCTIONS =====================================================*/
+
+/*
++------------------------------------------------------------------------------
+| Function    : sig_cia_sda_cia_decomp_ind
++------------------------------------------------------------------------------
+| Description : Handles the internal signal SIG_CIA_SDA_CIA_DECOMP_IND
+|
+| Parameters  : cia_decomp_ind, p_id
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sig_cia_sda_cia_decomp_ind (T_CIA_DECOMP_IND* cia_decomp_ind, UBYTE p_id) 
+{ 
+  UBYTE sapi_index = 0;
+  UBYTE sapi = 0;
+  UBYTE nsapi= cia_decomp_ind->pdu_ref.ref_nsapi;
+  BOOL rec = FALSE;
+  T_SN_DATA_IND* sn_data_ind = NULL;
+
+  TRACE_ISIG( "sig_cia_sda_cia_decomp_ind" );
+
+   /*
+    * set service instance according to sapi in primitive
+    */
+  sndcp_get_nsapi_sapi(cia_decomp_ind->pdu_ref.ref_nsapi, &sapi);
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+
+  
+  switch( sndcp_get_nsapi_rec_state(nsapi) )
+  {
+    case SDA_RECEIVE_FIRST_SEGMENT:
+    case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+    case SDA_ESTABLISH_REQUESTED:
+      {
+       
+        MALLOC(sn_data_ind, sizeof(T_SN_DATA_IND));
+
+#ifdef _SNDCP_DTI_2_
+        sn_data_ind->desc_list2.first = cia_decomp_ind->desc_list2.first;
+        sn_data_ind->desc_list2.list_len = cia_decomp_ind->desc_list2.list_len;
+#endif /*_SNDCP_DTI_2_*/
+
+#ifdef SNDCP_TRACE_ALL
+
+        sndcp_data->cia.cia_decomp_ind_number[nsapi] --;
+        TRACE_EVENT_P1("number of cia_decomp_ind: % d",
+                       sndcp_data->cia.cia_decomp_ind_number[nsapi]);
+#endif /* SNDCP_TRACE_ALL */
+
+        sn_data_ind->nsapi = nsapi;
+        sn_data_ind->p_id = p_id;
+        sda_is_nsapi_rec(nsapi, &rec);
+        if (rec) {
+          sda_set_nsapi_rec(nsapi, FALSE);
+          sig_sda_nd_data_ind(nsapi, 
+                              sn_data_ind, 
+                              (UBYTE)cia_decomp_ind->pdu_ref.ref_npdu_num);
+          sda_get_data_if_nec(sapi);
+        } else {
+          if (sndcp_data->sda->cur_sn_data_ind[nsapi] NEQ NULL)
+          {
+#ifndef NTRACE
+#ifdef SNDCP_TRACE_ALL
+            TRACE_EVENT_P1("Discard cur_sn.. in %s", sndcp_data->sda->state_name);
+#endif /* SNDCP_TRACE_ALL */
+#endif /* NTRACE */
+            sda_delete_cur_sn_data_ind(nsapi);
+          }
+          sndcp_data->sda->cur_sn_data_ind[nsapi] = sn_data_ind;
+          sndcp_data->sda->uncomp_npdu_num = 
+                               (UBYTE)cia_decomp_ind->pdu_ref.ref_npdu_num;
+          sndcp_set_nsapi_rec_state(nsapi, SDA_WAIT_NSAPI);
+          sda_get_data_if_nec ( sapi );
+        }
+      }
+      MFREE(cia_decomp_ind);
+      break;
+    default:
+      TRACE_ERROR( "SIG_CIA_SDA_CIA_DECOMP_IND unexpected" );
+      MFREE_PRIM(cia_decomp_ind); 
+      break;
+  }
+} /* sig_cia_sda_cia_decomp_ind() */
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : sig_mg_sda_delete_npdus
++------------------------------------------------------------------------------
+| Description : Handles the internal signal SIG_MG_SD_DELETE_NPDUS
+|
+| Parameters  : affected NSAPI, SAPI
+| Pre         : If the affected SAPI no longer uses acknowledged LLC operation
+|               mode, no LL_GETDATA_REQ shall be sent. So sndcp_sapi_state_ra
+|               must already be set to MG_REL_PENDING before this functon is 
+|               called (if that sub state is desired).
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sig_mg_sda_delete_npdus (UBYTE nsapi,
+                                    UBYTE sapi) 
+{ 
+  UBYTE sapi_index = 0;
+
+  TRACE_ISIG( "sig_mg_sda_delete_npdus" );
+
+   /*
+    * set service instance according to sapi in primitive
+    */
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+  
+  switch( sndcp_get_nsapi_rec_state(nsapi) )
+  {
+    case SDA_ESTABLISH_REQUESTED:
+    case SDA_RECEIVE_FIRST_SEGMENT:
+    case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+      if (sndcp_data->sda->cur_sn_data_ind[nsapi] != NULL) {
+        sda_delete_cur_sn_data_ind(nsapi);
+        sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+      } else {
+        sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+      }
+      break;
+    case SDA_WAIT_NSAPI:
+      if (sndcp_data->sda->cur_sn_data_ind[nsapi] != NULL) {
+        USHORT sapi_state = MG_IDLE;
+
+        sda_delete_cur_sn_data_ind(nsapi);
+        /*
+         * Does it make sense to request another acknowlegded segment or is
+         * the whole SAPI now using only unacknowledged mode?
+         */
+        sndcp_get_sapi_state(sapi, &sapi_state);
+        if ((sapi_state & MG_REL) == 0) {
+          sda_get_data_if_nec(sapi);
+        }
+        sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+      } 
+      break;
+    default:
+      TRACE_ERROR( "SIG_MG_SDA_DELETE_NPDUS unexpected" );
+      break;
+  }
+} /* sig_mg_sda_delete_npdus() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : sig_mg_sda_end_est
++------------------------------------------------------------------------------
+| Description : Handles the signal PD_SD_END_EST
+|
+| Parameters  : affected sapi, success
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sig_mg_sda_end_est (UBYTE sapi, BOOL success)
+{ 
+  UBYTE sapi_index = 0;
+  UBYTE nsapi = 0;
+
+  TRACE_FUNCTION( "sig_pda_sda_est_cnf" );
+
+   /*
+    * set service instance according to sapi in primitive
+    */
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+
+  /*
+   * Send LL_GETDATA_REQ. 
+   */
+  if (success){
+    sndcp_data->sda->llc_may_send = FALSE;
+    sda_get_data_if_nec(sapi);
+  }
+  /*
+   * All nsapis at this sapi that use ack mode, enter 
+   * SDA_ESTABLISH_REQUESTED state.
+   */
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) {
+    UBYTE local_sapi = 0;
+    BOOL used = FALSE;
+
+    sndcp_is_nsapi_used(nsapi, &used);
+    if (!used) {
+      continue;
+    }
+    sndcp_get_nsapi_sapi(nsapi, &local_sapi);
+    if (local_sapi == sapi) {
+      switch( sndcp_get_nsapi_rec_state(nsapi) )
+      {
+        case SDA_ESTABLISH_REQUESTED:
+        case SDA_RECEIVE_FIRST_SEGMENT:
+        case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+        case SDA_WAIT_NSAPI:
+        case SDA_ACK_DISCARD:
+          sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+          break;
+        default:
+          TRACE_EVENT( "SIG_MG_SDA_END_EST unexpected for this NSAPI" );
+          break;
+      }
+    }
+  } /* for all nsapis */
+
+
+} /* sig_mg_sda_end_est() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : sig_mg_sda_getdata
++------------------------------------------------------------------------------
+| Description : Handles the internal signal SIG_MG_SD_GETDATA
+|
+| Parameters  : sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sig_mg_sda_getdata (UBYTE sapi, UBYTE nsapi) 
+{ 
+  UBYTE sapi_index = 0;
+
+  TRACE_ISIG( "sig_mg_sda_getdata" );
+
+   /*
+    * set service instance according to sapi in primitive
+    */
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+  
+  switch( GET_STATE(SDA) )
+  {
+    case SDA_DEFAULT:
+      sda_get_data_if_nec(sapi);
+      sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+      break;
+    default:
+      TRACE_ERROR( "SIG_MG_SDA_GETDATA unexpected" );
+      break;
+  }
+} /* sig_mg_sda_getdata() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : sig_cia_sda_getdata
++------------------------------------------------------------------------------
+| Description : Handles the internal signal SIG_CIA_SDA_GETDATA
+|
+| Parameters  : sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sig_cia_sda_getdata (UBYTE sapi, UBYTE nsapi)
+{
+
+  TRACE_ISIG( "sig_cia_sda_getdata" );
+
+  switch( sndcp_get_nsapi_rec_state(nsapi) )
+  {
+    case SDA_RECEIVE_FIRST_SEGMENT:
+    case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+    case SDA_WAIT_NSAPI:
+      sda_get_data_if_nec(sapi);
+      break;
+    default:
+      TRACE_ERROR( "SIG_CIA_SDA_GETDATA unexpected" );
+      break;
+  }
+} /* sig_cia_sda_getdata() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : sig_nd_sda_getdata_req
++------------------------------------------------------------------------------
+| Description : Handles the internal signal SIG_ND_SDA_GETDATA_REQ
+|
+| Parameters  : affected sapi, affected nsapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sig_nd_sda_getdata_req (UBYTE sapi,
+                                    UBYTE nsapi) 
+{ 
+  UBYTE sapi_index = 0;
+
+  TRACE_ISIG( "sig_nd_sda_getdata_req" );
+
+   /*
+    * set service instance according to sapi in primitive
+    */
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+  
+  switch( sndcp_get_nsapi_rec_state(nsapi) )
+  {
+    case SDA_RECEIVE_FIRST_SEGMENT:
+    case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+      sda_set_nsapi_rec(nsapi, TRUE);
+      break;
+    case SDA_WAIT_NSAPI:
+      if (sndcp_data->sda->cur_sn_data_ind[nsapi] != NULL) {
+        /*
+         * Send the just reassembled N-PDU (must be present because of state!).
+         */
+        sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+        sig_sda_nd_data_ind(nsapi, 
+                            sndcp_data->sda->cur_sn_data_ind[nsapi], 
+                            sndcp_data->sda->uncomp_npdu_num);
+        sndcp_data->sda->cur_sn_data_ind[nsapi] = NULL;
+        sda_get_data_if_nec(sapi);
+      } else {
+        /*
+         * Set the receptive for the given nsapi.
+         */
+        sda_set_nsapi_rec(nsapi, TRUE);
+      }
+      break;
+    default:
+      TRACE_ERROR( "SIG_ND_SDA_GETDATA_REQ unexpected" );
+      break;
+  }
+} /* sig_nd_sda_getdata_req() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : sig_mg_sda_start_est
++------------------------------------------------------------------------------
+| Description : Handles the signal PD_SD_START_EST
+|
+| Parameters  : affected sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sig_mg_sda_start_est (UBYTE sapi)
+{ 
+  UBYTE nsapi = 0;
+
+  TRACE_FUNCTION( "sig_pda_sda_start_est" );
+  
+  /*
+   * All nsapis at this sapi that use ack mode, enter 
+   * SDA_ESTABLISH_REQUESTED state.
+   */
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) {
+    UBYTE sapi_help = 0;
+    BOOL used = FALSE;
+
+    sndcp_is_nsapi_used(nsapi, &used);
+    if (!used) {
+      continue;
+    }
+    sndcp_get_nsapi_sapi(nsapi, &sapi_help);
+    if (sapi_help == sapi) {
+      switch( sndcp_get_nsapi_rec_state(nsapi) )
+      {
+        case SDA_ESTABLISH_REQUESTED:
+        case SDA_RECEIVE_FIRST_SEGMENT:
+        case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+        case SDA_WAIT_NSAPI:
+          sndcp_set_nsapi_rec_state(nsapi, SDA_ESTABLISH_REQUESTED);
+          break;
+        default:
+          TRACE_EVENT( "SIG_MG_SDA_START_EST unexpected for this NSAPI" );
+          break;
+      }
+    }
+  } /* for all nsapis */
+
+} /* sig_mg_sda_start_est() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : sig_pd_sda_data_ind
++------------------------------------------------------------------------------
+| Description : Handles the signal PD_SD_DATA_IND
+|
+| Parameters  : *ll_data_ind - Ptr to primitive payload
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sig_pda_sda_data_ind ( T_LL_DATA_IND *ll_data_ind )
+{ 
+  UBYTE sapi_index = 0;
+  BOOL valid = FALSE;
+  UBYTE nsapi = 0;
+  UBYTE sapi = 0;
+
+  TRACE_FUNCTION( "sig_pda_sda_data_ind" );
+
+   /*
+    * set service instance according to sapi in primitive
+    */
+  sndcp_get_sapi_index(ll_data_ind->sapi, &sapi_index);
+  sndcp_data->sda = & sndcp_data->sda_base[sapi_index];
+  sda_get_nsapi(ll_data_ind, &nsapi);
+  
+  /*
+   * LLC has now "used up" it's pending LL_GETDATA_REQ and will have 
+   * to wait for the next one.
+   */
+  sndcp_data->sda->llc_may_send = FALSE;
+  sapi = ll_data_ind->sapi;
+
+  switch( sndcp_get_nsapi_rec_state(nsapi) )
+  {
+    case SDA_ESTABLISH_REQUESTED:
+      /* 
+       * Just discard the segment. Next segment will be requested after 
+       * confirmation of establishment.
+       */
+      PFREE(ll_data_ind);
+      ll_data_ind = NULL;
+      break;
+
+    case SDA_RECEIVE_FIRST_SEGMENT:
+      /* 
+       * Invalid segments are discarded without error notification
+       */
+      sda_is_seg_valid(ll_data_ind, &valid);
+      if (!valid) {
+        PFREE(ll_data_ind);
+        sda_get_data_if_nec(sapi);
+        return;
+      }
+      if (sda_f_bit(ll_data_ind)) {
+        if (sda_m_bit(ll_data_ind)) {
+          sda_ac_f_f1_m1(ll_data_ind);
+        } else {
+          sda_ac_f_f1_m0(ll_data_ind);
+        }
+      } else {
+        sda_ac_f_f0(ll_data_ind);
+      }
+      
+      break;
+
+    case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+      /* 
+       * Invalid segments are discarded without error notification
+       */
+      sda_is_seg_valid(ll_data_ind, &valid);
+      if (!valid) {
+        PFREE(ll_data_ind);
+        sda_get_data_if_nec(sapi);
+        return;
+      }
+      if (sda_f_bit(ll_data_ind)) {
+        if (sda_m_bit(ll_data_ind)) {
+          sda_ac_s_f1_m1(ll_data_ind);
+        } else {
+          sda_ac_s_f1_m0(ll_data_ind);
+        }
+      } else {
+        if (sda_m_bit(ll_data_ind)) {
+          sda_ac_s_f0_m1(ll_data_ind);
+        } else {
+          sda_ac_s_f0_m0(ll_data_ind);
+        }
+      }
+      
+      break;
+
+    case SDA_WAIT_NSAPI:
+      if (ll_data_ind != NULL)
+      {
+        PFREE(ll_data_ind);
+      }
+      sda_get_data_if_nec(sapi); 
+      break;
+
+    case SDA_ACK_DISCARD:
+      /*
+       * In this state we will discard every downlink segment till we receive.
+       * the last segment.
+       * Once we receive the last segment, we will move to the state
+       * SDA_RECEIVE_FIRST_SEGMENT.
+       */
+      TRACE_EVENT( "SDA_ACK_DISCARD state,Discard Segments ..." );
+      sndcp_data->cur_segment_number[nsapi] ++;
+      if (!sda_m_bit(ll_data_ind))
+      {
+        TRACE_EVENT( "Received the last Segment in SDA_ACK_DISCARD state " );
+        sndcp_data->cur_segment_number[nsapi] = 0;
+        sndcp_set_nsapi_rec_state(nsapi, SDA_RECEIVE_FIRST_SEGMENT);
+      }
+      PFREE(ll_data_ind);
+      sda_get_data_if_nec(sapi);
+      break;
+
+    default:
+      TRACE_ERROR( "SIG_PDA_SDA_DATA_IND unexpected" );
+      /*
+       * The primitive LL_DATA_IND is unexpected or the
+       * NSAPI value is wrong. Discard the prim and send a FC prim.
+       */
+      if (ll_data_ind != NULL)
+      {
+        PFREE(ll_data_ind);
+      }
+      sda_get_data_if_nec(sapi);
+      break;
+  }
+  
+} /* sig_pda_sda_data_ind() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : sig_mg_sda_reset_ind
++------------------------------------------------------------------------------
+| Description : Handles the internal signal SIG_MG_SDA_RESET_IND
+|
+| Parameters  : affected sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sig_mg_sda_reset_ind (UBYTE nsapi) 
+{ 
+
+  TRACE_ISIG( "sig_mg_sda_reset_ind" );
+
+  switch( sndcp_get_nsapi_rec_state(nsapi) )
+  {
+      case SDA_ESTABLISH_REQUESTED:
+      case SDA_RECEIVE_FIRST_SEGMENT:
+      case SDA_RECEIVE_SUBSEQUENT_SEGMENT:
+      case SDA_WAIT_NSAPI:
+      case SDA_ACK_DISCARD:
+        /*
+         * Similar to sd.
+         */
+        sndcp_data->cur_dcomp[nsapi] = 0;
+        sndcp_data->cur_pcomp[nsapi] = 0;
+      break;
+    default:
+      TRACE_ERROR( "SIG_MG_SDA_RESET_IND unexpected" );
+      break;
+  }
+} /* sig_mg_sda_reset_ind() */
+