diff gsm-fw/g23m-aci/uart/uart_dtxp.c @ 775:eedbf248bac0

gsm-fw/g23m-aci subtree: initial import from LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 12 Oct 2014 01:45:14 +0000
parents
children f54080301c98
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/g23m-aci/uart/uart_dtxp.c	Sun Oct 12 01:45:14 2014 +0000
@@ -0,0 +1,524 @@
+/* 
++----------------------------------------------------------------------------- 
+|  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 UART and implements all 
+|             functions to handles the incoming primitives as described in 
+|             the SDL-documentation (DTX-statemachine)
++----------------------------------------------------------------------------- 
+*/ 
+
+#ifndef UART_DTXP_C
+#define UART_DTXP_C
+#endif /* !UART_DTXP_C */
+
+#define ENTITY_UART
+
+/*==== INCLUDES =============================================================*/
+
+#ifdef WIN32
+#include "nucleus.h"
+#endif /* WIN32 */
+#include "typedefs.h"   /* to get Condat data types */
+#include "vsi.h"        /* to get a lot of macros */
+#include "macdef.h"     /* to get a lot of macros */
+#include "custom.h"
+#include "gsm.h"        /* to get a lot of macros */
+#include "cnf_uart.h"   /* to get cnf-definitions */
+#include "mon_uart.h"   /* to get mon-definitions */
+#include "prim.h"       /* to get the definitions of used SAP and directions */
+#ifdef DTILIB
+#include "dti.h"        /* to get dti lib */
+#endif /* DTILIB */
+#include "pei.h"        /* to get PEI interface */
+#ifdef FF_MULTI_PORT
+#include "gsi.h"        /* to get definitions of serial driver */
+#else /* FF_MULTI_PORT */
+#ifdef _TARGET_
+#include "uart/serialswitch.h"
+#include "uart/traceswitch.h"
+#else /* _TARGET_ */
+#include "serial_dat.h" /* to get definitions of serial driver */
+#endif /* _TARGET_ */
+#endif /* FF_MULTI_PORT */
+#include "uart.h"       /* to get the global entity definitions */
+
+#include "uart_dtxf.h"  /* to get DTX function definitions */
+#include "uart_dtxp.h"  /* to get DTX primitive definitions */
+#include "uart_kers.h"  /* to get signal definitions of service KER */
+#ifdef FF_MULTI_PORT
+#include "uart_prxs.h"  /* to get signal definitions for service TX */
+#else /* FF_MULTI_PORT */
+#include "uart_rxs.h"   /* to get signal definitions of service RX */
+#endif /* FF_MULTI_PORT */
+
+#ifdef _SIMULATION_
+#include <stdio.h>      /* to get sprintf */
+#endif /* _SIMULATION_ */
+#include <string.h>    /* JK, delete warnings: to get memcpy */
+
+/*==== CONST ================================================================*/
+
+/*==== LOCAL VARS ===========================================================*/
+
+/*==== PRIVATE FUNCTIONS ====================================================*/
+
+/*==== PUBLIC FUNCTIONS =====================================================*/
+
+
+#ifdef DTILIB
+
+/*
++------------------------------------------------------------------------------
+| Function    : sig_dti_dtx_tx_buffer_ready_ind
++------------------------------------------------------------------------------
+| Description : Handles the DTILIB callback call DTI_REASON_TX_BUFFER_READY
+|               
+|               This signal means that data may be sent over a dti connection.
+|
+| Parameters  : -
+|
++------------------------------------------------------------------------------
+ *
+ * when not using DTILIB, the functionality of sig_dti_dtx_tx_buffer_ready_ind()
+ * is to be found in dtx_dti_getdata_req(). When debugging, please have a look at
+ * both versions!!
+ */
+
+GLOBAL void sig_dti_dtx_tx_buffer_ready_ind()
+{
+  USHORT            old_write_pos;
+  T_DATA_FLOW_STATE old_data_flow;
+  T_desc2*          temp_desc;
+
+  TRACE_FUNCTION( "sig_dti_dtx_tx_buffer_ready_ind" );
+
+#ifdef FLOW_TRACE
+  sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_UP, FLOW_TRACE_TOP, TRUE);
+#endif /* FLOW_TRACE */
+  switch( GET_STATE( UART_SERVICE_DTX ) )
+  {
+    case DTX_NOT_READY:
+      old_data_flow = uart_data->dtx->data_flow;
+      old_write_pos = uart_data->dtx->write_pos;
+      /*
+       * enable data flow if necessary
+       */
+      if(uart_data->dtx->data_flow NEQ UART_FLOW_ENABLED)
+      {
+        uart_data->dtx->data_flow = UART_FLOW_ENABLED;
+        sig_dtx_ker_enable_ind(uart_data->dtx->dlc_instance);
+      }
+
+        if(uart_data->dtx->receiving_state EQ UART_DTX_NOT_RECEIVING)
+        {
+          /*
+           * if data to send available or
+           * line states changed
+           */
+          if((uart_data->dtx->to_send_data->len) ||
+             (uart_data->dtx->lines_changed))
+          {
+            PALLOC_DESC2 (dti_data_ind, DTI2_DATA_IND);
+            SET_STATE( UART_SERVICE_DTX, DTX_NOT_READY );
+
+            if(uart_data->dtx->to_send_data->len)
+            {
+              /*
+               * mark entity descriptor as invalid, since data will be forwarded
+               */
+              temp_desc                    = uart_data->dtx->to_send_data;
+              uart_data->dtx->to_send_data = NULL;
+
+              dti_data_ind->desc_list2.first    = (ULONG)temp_desc;
+              dti_data_ind->desc_list2.list_len = temp_desc->len;
+
+              /*
+               * calculate new size multiplier according to fillrate of buffer
+               */
+              dtx_calculate_size_multiplier (temp_desc, old_data_flow);
+              /*
+               * allocate a new descriptor with size according to new size_multiplier
+               */
+              dtx_allocate_resources();
+              /*
+               * Check for data which has not yet been validated, i.e. because
+               * the frame containing the data has not yet been received completely.
+               * In this case, the not yet validated data is copied to the newly
+               * allocated descriptor.
+               */
+              if(old_write_pos > temp_desc->len)
+              {
+                memcpy(uart_data->dtx->to_send_data->buffer,
+                       &temp_desc->buffer[temp_desc->len],
+                       old_write_pos - temp_desc->len);
+                uart_data->dtx->write_pos = old_write_pos - temp_desc->len;
+              }
+              uart_data->dtx->esd_pos-= temp_desc->len;
+            }
+            else
+            {
+              /*
+               * just line states has been changed
+               */
+              dti_data_ind->desc_list2.first    = (ULONG)NULL;
+              dti_data_ind->desc_list2.list_len = 0;
+            }
+
+            /*
+             * set line states and
+             * mark line states as unchanged;
+             */
+#ifdef DTI2
+            dti_data_ind->parameters.st_lines.st_flow         = uart_data->dtx->st_flow;
+            dti_data_ind->parameters.st_lines.st_line_sa      = uart_data->dtx->st_line_sa;
+            dti_data_ind->parameters.st_lines.st_line_sb      = uart_data->dtx->st_line_sb;
+            dti_data_ind->parameters.st_lines.st_line_sb      = uart_data->dtx->st_line_sb;
+            dti_data_ind->parameters.st_lines.st_break_len    = uart_data->dtx->st_break_len;
+#else  /* DTI2 */
+            dti_data_ind->st_flow         = uart_data->dtx->st_flow;
+            dti_data_ind->st_line_sa      = uart_data->dtx->st_line_sa;
+            dti_data_ind->st_line_sb      = uart_data->dtx->st_line_sb;
+            dti_data_ind->st_line_sb      = uart_data->dtx->st_line_sb;
+            dti_data_ind->st_escape       = uart_data->dtx->st_escape;
+            dti_data_ind->tui  = uart_data->tui_uart;
+#endif /* DTI2 */
+            uart_data->dtx->lines_changed = FALSE;
+            uart_data->dtx->st_break_len  = DTI_BREAK_OFF;
+
+#ifdef _SIMULATION_
+#ifndef DTI2
+            dti_data_ind->op_ack = OP_UNACK;
+#endif /* !DTI2 */
+#else /* _SIMULATION_ */
+#ifdef FLOW_TRACE
+            sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_UP, FLOW_TRACE_TOP, FALSE);
+#endif /* FLOW_TRACE */
+#endif /* _SIMULATION_ */
+            dti_send_data(
+              uart_hDTI,
+              uart_data->device,
+              UART_DTI_UP_INTERFACE,
+              uart_data->dtx->dlc_instance,
+              dti_data_ind
+              );
+          }
+          else
+          {
+            /*
+             * no data to send
+             */
+            SET_STATE( UART_SERVICE_DTX, DTX_READY );
+          }
+          sig_dtx_rx_ready_to_receive_req( uart_data->dtx->dlc_instance,
+                                           uart_data->dtx->to_send_data, 
+                                           uart_data->dtx->write_pos, 
+                                           uart_data->dtx->cur_desc_size );
+        }
+        else
+        {
+          /*
+           * DTX service is currently receiving,
+           * data will be forwarded to upper layer when 
+           * sig_rx_dtx_data_received_ind() is called
+           */
+          SET_STATE( UART_SERVICE_DTX, DTX_READY );
+        }
+        break;
+
+    default:
+      TRACE_FUNCTION( "DTI_GETDATA_REQ unexpected" );
+      break;
+  }
+} /* sig_dti_dtx_tx_buffer_ready_ind() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : sig_dti_dtx_tx_buffer_full_ind
++------------------------------------------------------------------------------
+| Description : Handles the DTILIB callback call DTI_REASON_TX_BUFFER_FULL
+|               Since no send queue is used, this function does not have
+|               any functionality by now
+|               
+|               This signal means that data may not be sent over a dti connection.
+|
+| Parameters  : -
+|
++------------------------------------------------------------------------------
+*/
+
+GLOBAL void sig_dti_dtx_tx_buffer_full_ind()
+{
+  TRACE_FUNCTION( "sig_dti_dtx_tx_buffer_full_ind" );
+} /* sig_dti_dtx_tx_buffer_full_ind() */
+
+#else  /* DTILIB */
+/*
++------------------------------------------------------------------------------
+| Function    : dtx_dti_getdata_req
++------------------------------------------------------------------------------
+| Description : Handles the primitive DTI_GETDATA_REQ
+|
+| Parameters  : *dti_getdata_req - Ptr to primitive payload
+|
++------------------------------------------------------------------------------
+ *
+ * when using DTILIB, the functionality of dtx_dti_getdata_req() is to be found
+ * in sig_dti_dtx_tx_buffer_ready_ind(). When debugging, please have a look at
+ * both versions!!
+ */
+GLOBAL void dtx_dti_getdata_req ( T_DTI_GETDATA_REQ *dti_getdata_req )
+{
+  USHORT            old_write_pos;
+  T_DATA_FLOW_STATE old_data_flow;
+  T_desc2*          temp_desc;
+
+  TRACE_FUNCTION( "dtx_dti_getdata_req" );
+
+#ifdef FLOW_TRACE
+  sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_UP, FLOW_TRACE_TOP, TRUE);
+#endif /* FLOW_TRACE */
+
+#ifdef UART_RANGE_CHECK
+  if(dti_getdata_req EQ NULL)
+  {
+    TRACE_EVENT("ERROR: dti_getdata_req is NULL");
+  }
+  else if((*((ULONG*)((UBYTE*)dti_getdata_req - sizeof(T_PRIM_HEADER) - 8))) NEQ 0)
+  {
+    TRACE_EVENT_P1("ERROR: dti_getdata_req=%08x is not allocated",
+                    dti_getdata_req);
+  }
+#endif /* UART_RANGE_CHECK */
+
+  if( pei_select_instances( dti_getdata_req->c_id ) EQ TRUE )
+  {
+    switch( GET_STATE( UART_SERVICE_DTX ) )
+    {
+      case DTX_NOT_READY:
+        old_data_flow = uart_data->dtx->data_flow;
+        old_write_pos = uart_data->dtx->write_pos;
+        /*
+         * enable data flow if necessary
+         */
+        if(uart_data->dtx->data_flow NEQ UART_FLOW_ENABLED)
+        {
+          uart_data->dtx->data_flow = UART_FLOW_ENABLED;
+          sig_dtx_ker_enable_ind(uart_data->dtx->dlc_instance);
+        }
+
+        if(uart_data->dtx->receiving_state EQ UART_DTX_NOT_RECEIVING)
+        {
+          /*
+           * if data to send available or
+           * line states changed
+           */
+          if((uart_data->dtx->to_send_data->len) ||
+             (uart_data->dtx->lines_changed))
+          {
+            PALLOC_DESC2 (dti_data_ind, DTI_DATA_IND);
+            SET_STATE( UART_SERVICE_DTX, DTX_NOT_READY );
+
+            if(uart_data->dtx->to_send_data->len)
+            {
+              /*
+               * mark entity descriptor as invalid, since data will be forwarded
+               */
+              temp_desc                    = uart_data->dtx->to_send_data;
+              uart_data->dtx->to_send_data = NULL;
+
+              dti_data_ind->desc_list2.first    = (ULONG)temp_desc;
+              dti_data_ind->desc_list2.list_len = temp_desc->len;
+
+              /*
+               * calculate new size multiplier according to fillrate of buffer
+               */
+              dtx_calculate_size_multiplier (temp_desc, old_data_flow);
+              /*
+               * allocate a new descriptor with size according to new size_multiplier
+               */
+              dtx_allocate_resources();
+              /*
+               * Check for data which has not yet been validated, i.e. because
+               * the frame containing the data has not yet been received completely.
+               * In this case, the not yet validated data is copied to the newly
+               * allocated descriptor.
+               */
+              if(old_write_pos > temp_desc->len)
+              {
+                memcpy(uart_data->dtx->to_send_data->buffer,
+                       &temp_desc->buffer[temp_desc->len],
+                       old_write_pos - temp_desc->len);
+                uart_data->dtx->write_pos = old_write_pos - temp_desc->len;
+              }
+              uart_data->dtx->esd_pos-= temp_desc->len;
+            }
+            else
+            {
+              /*
+               * just line states has been changed
+               */
+              dti_data_ind->desc_list2.first    = (ULONG)NULL;
+              dti_data_ind->desc_list2.list_len = 0;
+            }
+
+            /*
+             * set line states and
+             * mark line states as unchanged;
+             */
+            dti_data_ind->st_flow         = uart_data->dtx->st_flow;
+            dti_data_ind->st_line_sa      = uart_data->dtx->st_line_sa;
+            dti_data_ind->st_line_sb      = uart_data->dtx->st_line_sb;
+            dti_data_ind->st_line_sb      = uart_data->dtx->st_line_sb;
+            dti_data_ind->st_escape       = uart_data->dtx->st_escape;
+            uart_data->dtx->lines_changed = FALSE;
+            uart_data->dtx->st_escape     = DTI_ESC_OFF;
+
+            dti_data_ind->tui  = uart_data->tui_uart;
+            dti_data_ind->c_id = dtx_get_channel_id();
+#ifdef _SIMULATION_
+            dti_data_ind->op_ack = OP_UNACK;
+
+            dtx_psend_dti_data_test_ind(dti_data_ind);
+#else /* _SIMULATION_ */
+#ifdef FLOW_TRACE
+            sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_UP, FLOW_TRACE_TOP, FALSE);
+#endif /* FLOW_TRACE */
+            PSEND (uart_data->dtx->hComm_DTX_UPLINK, dti_data_ind);
+#endif /* _SIMULATION_ */
+          }
+          else
+          {
+            /*
+             * no data to send
+             */
+            SET_STATE( UART_SERVICE_DTX, DTX_READY );
+          }
+          sig_dtx_rx_ready_to_receive_req( uart_data->dtx->dlc_instance,
+                                           uart_data->dtx->to_send_data, 
+                                           uart_data->dtx->write_pos, 
+                                           uart_data->dtx->cur_desc_size );
+        }
+        else
+        {
+          /*
+           * DTX service is currently receiving,
+           * data will be forwarded to upper layer when 
+           * sig_rx_dtx_data_received_ind() is called
+           */
+          SET_STATE( UART_SERVICE_DTX, DTX_READY );
+        }
+        break;
+
+      default:
+        TRACE_FUNCTION( "DTI_GETDATA_REQ unexpected" );
+        break;
+    }
+  }
+  PFREE( dti_getdata_req );
+} /* dtx_dti_getdata_req() */
+#endif /* DTILIB */
+
+
+#if defined ( _SIMULATION_ )
+#ifndef DTILIB
+/*
++------------------------------------------------------------------------------
+| Function    : dtx_psend_dti_data_test_ind
++------------------------------------------------------------------------------
+| Description : Copies the content of the given DTI DATA IND primitive to a new
+|               DTI_DATA_TEST_IND primitive, sends the primitive 
+|               DTI_DATA_TEST_IND to hCommUPLINK and frees the original 
+|               DTI_DATA_IND primitive. 
+|               Note: function is only needed in case of simulation target
+|
+| Parameters  : *dti_data_ind - Ptr to primitive payload
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void dtx_psend_dti_data_test_ind ( T_DTI_DATA_IND *dti_data_ind )
+{
+  T_desc2* temp_desc;
+  USHORT  packet_len;
+  USHORT  pos;
+  char    buf[100];
+  USHORT  i;
+
+  TRACE_FUNCTION( "dtx_psend_dti_data_test_ind" );
+
+  /*
+   * create new primitive and copy all parameters into new primitive
+   */
+  packet_len = dti_data_ind->desc_list2.list_len;
+  {
+    PALLOC_SDU (dti_data_test_ind, 
+                DTI_DATA_TEST_IND, 
+                (USHORT)(packet_len << 3));
+    dti_data_test_ind->tui        = dti_data_ind->tui;
+    dti_data_test_ind->c_id       = dti_data_ind->c_id;
+    dti_data_test_ind->p_id       = dti_data_ind->p_id;
+    dti_data_test_ind->op_ack     = dti_data_ind->op_ack;
+    dti_data_test_ind->st_flow    = dti_data_ind->st_flow;
+    dti_data_test_ind->st_line_sa = dti_data_ind->st_line_sa;
+    dti_data_test_ind->st_line_sb = dti_data_ind->st_line_sb;
+    dti_data_test_ind->st_escape  = dti_data_ind->st_escape;
+    /*
+     * copy generic data descriptor in sdu
+     */
+    temp_desc = (T_desc2*)dti_data_ind->desc_list2.first;
+    dti_data_test_ind->sdu.o_buf = 0;
+    dti_data_test_ind->sdu.l_buf = (packet_len << 3);
+    pos = 0;
+    while(temp_desc)
+    {
+      memcpy(&dti_data_test_ind->sdu.buf[pos], 
+             temp_desc->buffer, 
+             temp_desc->len);
+      pos      += temp_desc->len;
+      temp_desc = (T_desc2*)temp_desc->next;
+    }
+    /*
+     * trace output 
+     */
+    i   = 0;
+    pos = 0;
+    while(pos < packet_len)
+    {
+      i+= sprintf(&buf[i], "0x%02x, ", dti_data_test_ind->sdu.buf[pos]);
+      pos++;
+      if(i > 80)
+      {
+        TRACE_FUNCTION( buf );
+        i = 0;
+      }
+      else if(pos >= packet_len)
+      {
+        TRACE_FUNCTION( buf );
+      }
+    }
+    /*
+     * send primitive
+     */
+    PSEND (uart_data->dtx->hComm_DTX_UPLINK, dti_data_test_ind);
+  }
+  /*
+   * free the primitive
+   */
+  PFREE_DESC(dti_data_ind);
+} /* dtx_psend_dti_data_test_ind() */
+#endif /* !DTILIB */
+#endif /* _SIMULATION_ */
+