diff src/g23m-gprs/sndcp/sndcp_suap.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_suap.c	Thu Oct 13 04:24:13 2016 +0000
@@ -0,0 +1,366 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  GPRS (8441)
+|  Modul   :  sndcp_suap.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 primitives as described in 
+|             the SDL-documentation (SUA-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 "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_suaf.h"     /* to get internal functions of service sua */
+#include "sndcp_nus.h"     /* to get signal functions to service nu */
+
+
+/*==== CONST ================================================================*/
+
+/*==== LOCAL VARS ===========================================================*/
+
+/*==== PRIVATE FUNCTIONS ====================================================*/
+
+/*==== PUBLIC FUNCTIONS =====================================================*/
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : sua_ll_data_cnf
++------------------------------------------------------------------------------
+| Description : Handles the primitive LL_DATA_CNF
+|
+| Parameters  : *ll_data_cnf - Ptr to primitive payload
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sua_ll_data_cnf ( T_LL_DATA_CNF *ll_data_cnf )
+{ 
+  BOOL complete = FALSE;
+  BOOL found = FALSE;
+  T_SEG_INFO* help = NULL;
+  T_SEG_INFO* last_help = NULL;
+  UBYTE sapi_index = 0;
+  UBYTE refi = 0;
+
+  TRACE_FUNCTION( "sua_ll_data_cnf" );
+
+   /*
+    * set service instance according to sapi in primitive
+    */
+  sndcp_get_sapi_index(ll_data_cnf->sapi, &sapi_index);
+  sndcp_data->sua = & sndcp_data->sua_base[sapi_index];
+
+  TRACE_EVENT_P1("ll_data_cnf->c_reference1: %d", ll_data_cnf->c_reference1);
+  
+  switch( GET_STATE( SUA ) )
+  {
+    case SUA_LLC_NOT_RECEPTIVE_SUSPEND:
+    case SUA_LLC_RECEPTIVE_SUSPEND:
+    case SUA_LLC_NOT_RECEPTIVE:
+    case SUA_LLC_RECEPTIVE:
+      for (refi = 0; refi < ll_data_cnf->c_reference1; refi++) {
+        complete = FALSE;
+        found = FALSE;
+        last_help = NULL;
+        help = sndcp_data->sua->first_seg_info;
+        if (help == NULL) {
+          /*
+           * There are no N-PDUs buffered. CNF must be wrong.
+           */
+          if (ll_data_cnf != NULL) {
+            TRACE_EVENT("There are no N-PDUs buffered. CNF must be wrong.");
+            PFREE(ll_data_cnf);
+          }
+          return;
+        }
+        while (help != NULL && !found) {
+          TRACE_EVENT_P1("ll_data_cnf->reference1[refi].ref_nsapi: %d",
+                         ll_data_cnf->reference1[refi].ref_nsapi);
+          TRACE_EVENT_P1("ll_data_cnf->reference1[refi].ref_npdu_num: %d",
+                         ll_data_cnf->reference1[refi].ref_npdu_num);
+          TRACE_EVENT_P1("ll_data_cnf->reference1[refi].ref_seg_num: %d",
+                         ll_data_cnf->reference1[refi].ref_seg_num);
+          if (ll_data_cnf->reference1[refi].ref_nsapi == help->nsapi &&
+            ll_data_cnf->reference1[refi].ref_npdu_num == help->npdu_number) 
+          {
+            TRACE_EVENT_P1("ll_data_cnf->reference1[refi].ref_seg_num: %d",
+                           ll_data_cnf->reference1[refi].ref_seg_num);
+            TRACE_EVENT_P1("old help->cnf_segments: %d", help->cnf_segments);
+            help->cnf_segments += 
+              1 << ll_data_cnf->reference1[refi].ref_seg_num;
+            TRACE_EVENT_P1("new help->cnf_segments: %d", help->cnf_segments);
+            found = TRUE;
+          }
+          last_help = help;
+          help = help->next;
+        }
+        if (!found) {
+          /*
+           * No affected NPDU found.
+           */
+          if (ll_data_cnf != NULL) {
+            TRACE_EVENT("No affected NPDU found.");
+            PFREE(ll_data_cnf);
+          }
+          return;
+        }
+
+        /*
+         * If the affected N-PDU is completely confirmed, notify service nu and
+         * free last_help.
+         */
+
+        TRACE_EVENT_P1("last_help->number_of_segments: %d", 
+                       last_help->number_of_segments);
+        TRACE_EVENT_P1("last_help->cnf_segments: %d", 
+                       last_help->cnf_segments);
+
+        if (last_help->number_of_segments == SNDCP_SEGMENT_NUMBERS_ACK) {
+          if (last_help->cnf_segments ==
+            SNDCP_MAX_COMPLETE /*4294967295 == 2**32 - 1*/) {
+            complete = TRUE;
+          }
+        } else if (last_help->cnf_segments == 
+          ((ULONG)(1 << last_help->number_of_segments) - 1)) {
+          complete = TRUE;
+        }
+        if (complete) {
+          /*
+           * Notify service nu.
+           */
+          sig_sua_nu_data_cnf
+            (ll_data_cnf->reference1[refi].ref_nsapi, 
+            (UBYTE)ll_data_cnf->reference1[refi].ref_npdu_num);
+          /*
+           * Free last_help.
+           */
+          help = sndcp_data->sua->first_seg_info;
+          if (help == last_help) {
+            sndcp_data->sua->first_seg_info = help->next;
+            MFREE(help);
+            help = NULL;
+          } else {
+            T_SEG_INFO* help_next = help->next;
+            while (help->next != last_help) {
+              help = help->next;
+            }
+            help_next = help->next;
+            help->next = help_next->next;
+            MFREE (help_next);
+          }
+        }
+      } /* for refi */
+      break;
+    default:
+      TRACE_ERROR( "LL_DATA_CNF unexpected" );
+      break;
+  }
+  if (ll_data_cnf != NULL) {
+    PFREE(ll_data_cnf);
+  }
+
+} /* sua_ll_data_cnf() */
+
+
+#ifdef _SNDCP_DTI_2_
+/*
++------------------------------------------------------------------------------
+| Function    : sua_ll_ready_ind
++------------------------------------------------------------------------------
+| Description : Handles the primitive LL_READY_IND
+|
+| Parameters  : *ll_ready_ind - Ptr to primitive payload
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sua_ll_ready_ind ( T_LL_READY_IND *ll_ready_ind )
+{ 
+  U8 sapi_index = 0;
+
+  TRACE_FUNCTION( "sua_ll_ready_ind" );
+
+   /*
+    * set service instance according to sapi in primitive
+    */
+  sndcp_get_sapi_index(ll_ready_ind->sapi, &sapi_index);
+  sndcp_data->sua = & sndcp_data->sua_base[sapi_index];
+
+  switch( GET_STATE( SUA ) )
+  {
+    case SUA_LLC_NOT_RECEPTIVE_SUSPEND:
+      /*
+       * Is queue with outgoing LL_DESC_REQs empty?
+       */
+      if (sndcp_data->sua->ll_desc_q_read ==
+          sndcp_data->sua->ll_desc_q_write) {
+        if (sndcp_data->sua->cia_state == CIA_IDLE) {
+          sua_next_sn_data_req(ll_ready_ind->sapi);
+        }
+      }
+      SET_STATE(SUA, SUA_LLC_RECEPTIVE_SUSPEND);
+      break;
+    case SUA_LLC_RECEPTIVE_SUSPEND:
+      break;
+    case SUA_LLC_NOT_RECEPTIVE:
+      /*
+       * Is queue with outgoing LL_DESC_REQs empty?
+       */
+      if (sndcp_data->sua->ll_desc_q_read ==
+          sndcp_data->sua->ll_desc_q_write) {
+        SET_STATE(SUA, SUA_LLC_RECEPTIVE);
+        if (sndcp_data->sua->cia_state == CIA_IDLE) {
+          sua_next_sn_data_req(ll_ready_ind->sapi);
+        }
+      } else { /* sndcp_data->sua.ll_desc_q is not empty */
+        /*
+         * Send next ll_desc_req from queue.
+         */
+        T_LL_DESC_REQ* ll_desc_req = 
+          sndcp_data->sua->ll_desc_q[sndcp_data->sua->ll_desc_q_read];
+        
+        U8 ll_desc_sapi    = ll_desc_req->sapi;
+        U8 ll_desc_seg_pos = ll_desc_req->seg_pos;
+        U8 ll_desc_nsapi   = sua_get_nsapi(ll_desc_req);
+
+        sndcp_data->sua->ll_desc_q[sndcp_data->sua->ll_desc_q_read] = NULL;
+        sndcp_data->sua->ll_desc_q_read =
+          (sndcp_data->sua->ll_desc_q_read + 1) % SNDCP_SEGMENT_NUMBERS_ACK;
+
+#ifdef _SIMULATION_
+        su_send_ll_data_req_test(ll_desc_req);
+#else /* _SIMULATION_ */ 
+        PSEND(hCommLLC, ll_desc_req);
+#endif /* _SIMULATION_ */
+
+        if ((ll_desc_seg_pos & SEG_POS_LAST) > 0) {
+          sig_sua_nu_ready_ind( ll_desc_nsapi );
+          sua_next_sn_data_req( ll_desc_sapi );
+          sndcp_data->sua->cia_state = CIA_IDLE;
+        }
+
+
+      } /* sndcp_data->sua.ll_desc_q is not empty */
+      break;
+    case SUA_LLC_RECEPTIVE:
+      break;
+    default:
+      TRACE_ERROR( "LL_READY_IND unexpected" );
+      break;
+  }
+  if (ll_ready_ind != NULL) {
+    PFREE (ll_ready_ind);
+  }
+
+} /* su_ll_ready_ind() */
+#else /* _SNDCP_DTI_2_ */
+/*
++------------------------------------------------------------------------------
+| Function    : sua_ll_ready_ind
++------------------------------------------------------------------------------
+| Description : Handles the primitive LL_READY_IND
+|
+| Parameters  : *ll_ready_ind - Ptr to primitive payload
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void sua_ll_ready_ind ( T_LL_READY_IND *ll_ready_ind )
+{ 
+  UBYTE sapi_index = 0;
+
+  TRACE_FUNCTION( "sua_ll_ready_ind" );
+
+   /*
+    * set service instance according to sapi in primitive
+    */
+  sndcp_get_sapi_index(ll_ready_ind->sapi, &sapi_index);
+  sndcp_data->sua = & sndcp_data->sua_base[sapi_index];
+
+  switch( GET_STATE( SUA ) )
+  {
+    case SUA_LLC_NOT_RECEPTIVE_SUSPEND:
+      /*
+       * Is queue with outgoing LL_DATA_REQs empty?
+       */
+      if (sndcp_data->sua->ll_data_q_read ==
+          sndcp_data->sua->ll_data_q_write) {
+        if (sndcp_data->sua->cia_state == CIA_IDLE) {
+          sua_next_sn_data_req(ll_ready_ind->sapi);
+        }
+      }
+      SET_STATE(SUA, SUA_LLC_RECEPTIVE_SUSPEND);
+      break;
+    case SUA_LLC_RECEPTIVE_SUSPEND:
+      break;
+    case SUA_LLC_NOT_RECEPTIVE:
+      /*
+       * Is queue with outgoing LL_DATA_REQs empty?
+       */
+      if (sndcp_data->sua->ll_data_q_read ==
+          sndcp_data->sua->ll_data_q_write) {
+        SET_STATE(SUA, SUA_LLC_RECEPTIVE);
+        if (sndcp_data->sua->cia_state == CIA_IDLE) {
+          sua_next_sn_data_req(ll_ready_ind->sapi);
+        }
+      } else { /* sndcp_data->sua.ll_data_q is not empty */
+        /*
+         * Send next ll_data_req from queue.
+         */
+        T_LL_DATA_REQ* ll_data_req = 
+          sndcp_data->sua->ll_data_q[sndcp_data->sua->ll_data_q_read];
+        
+        UBYTE ll_data_sapi    = ll_data_req->sapi;
+        UBYTE ll_data_seg_pos = ll_data_req->seg_pos;
+        UBYTE ll_data_nsapi   = sua_get_nsapi(ll_data_req);
+
+        sndcp_data->sua->ll_data_q[sndcp_data->sua->ll_data_q_read] = NULL;
+        sndcp_data->sua->ll_data_q_read =
+          (sndcp_data->sua->ll_data_q_read + 1) % SNDCP_SEGMENT_NUMBERS_ACK;
+
+        PSEND (hCommLLC, ll_data_req);
+
+        if ((ll_data_seg_pos & SEG_POS_LAST) > 0) {
+          sig_sua_nu_ready_ind( ll_data_nsapi );
+          sua_next_sn_data_req( ll_data_sapi );
+          sndcp_data->sua->cia_state = CIA_IDLE;
+        }
+
+
+      } /* sndcp_data->sua.ll_data_q is not empty */
+      break;
+    case SUA_LLC_RECEPTIVE:
+      break;
+    default:
+      TRACE_ERROR( "LL_READY_IND unexpected" );
+      break;
+  }
+  if (ll_ready_ind != NULL) {
+    PFREE (ll_ready_ind);
+  }
+
+} /* su_ll_ready_ind() */
+#endif /* _SNDCP_DTI_2_ */