view src/g23m-gprs/sndcp/sndcp_nup.c @ 673:62a5285e014a

Lorekeeping: allow tpudrv-leonardo.lib on Leonardo/Tango Back in 2015 the Mother's idea was to produce a FreeCalypso development board that would be a clone of TI Leonardo, including the original quadband RFFE; one major additional stipulation was that this board needed to be able to run original unmodified TCS211-20070608 firmware with all blobs intact, with only minimal binary patches to main.lib and tpudrv.lib. The necessary patched libs were produced at that time in the tcs211-patches repository. That plan was changed and we produced FCDEV3B instead, with Openmoko's triband RFFE instead of Leonardo quadband, but when FC Magnetite started in 2016, a TPUDRV_blob= provision was still made, allowing the possibility of patching OM's tpudrv.lib for a restored Leonardo RFFE. Now in 2020 we have FC Tango which is essentially a verbatim clone of Leonardo core, including the original quadband RFFE. We have also deblobbed our firmware so much that we have absolutely no real need for a blob version of tpudrv.lib - but I thought it would be neat to put the ancient TPUDRV_blob= mechanism (classic config) to its originally intended use, just for the heck of it.
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 29 May 2020 03:55:36 +0000
parents 219afcfc6250
children
line wrap: on
line source

/*
+-----------------------------------------------------------------------------
|  Project :  GPRS (8441)
|  Modul   :  sndcp_nup.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 (NU-statemachine)
+-----------------------------------------------------------------------------
*/

/*---- HISTORY --------------------------------------------------------------*/

#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_nuf.h"    /* to get functions from nu service */
#include "sndcp_sus.h"    /* to get internal signals to su signals */
#include "sndcp_suas.h"    /* to get internal signals to sua signals */


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

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

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

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


/*
+------------------------------------------------------------------------------
| Function    : nu_connection_state
+------------------------------------------------------------------------------
| Description : DTI connnection has been opened by calling sndcp_sig_callback
|               with reason DTI_REASON_CONNECTION_OPENED.
|
| Parameters  : UBYTE nsapi: the affected NSAPI
|
+------------------------------------------------------------------------------
*/
GLOBAL void nu_connection_state (UBYTE nsapi, BOOL opened)
{
  TRACE_ISIG( "nu_connection_state" );

  /*
   * set service instance according to nsapi in primitive
   */
  sndcp_data->nu = & sndcp_data->nu_base[nsapi];

  switch( GET_STATE( NU ) )
  {

    case NU_UNACK_SU_RECEPTIVE :
    case NU_UNACK_SU_NOT_RECEPTIVE:
#ifndef NCONFIG
    case NU_SEND_UNACK_SU_RECEPTIVE:
    case NU_SEND_UNACK_SU_NOT_RECEPTIVE:
#endif /* NCONFIG */
      if (!sndcp_data->nu->connection_is_opened
          &&
          opened) {
        sndcp_data->nu->connection_is_opened = TRUE;
#ifndef SNDCP_UPM_INCLUDED
        if (sndcp_data->nu->sn_switch_cnf_expected) {
          PALLOC (sn_switch_cnf, SN_SWITCH_CNF);
          sn_switch_cnf->nsapi = nsapi;
          sndcp_data->nu->sn_switch_cnf_expected = FALSE;
          PSEND(hCommMMI, sn_switch_cnf);
        }
#endif /*SNDCP_UPM_INCLUDED*/
#ifdef SNDCP_UPM_INCLUDED
        {
          U32 linkid = 0;
          PALLOC (sn_dti_cnf, SN_DTI_CNF);
          sndcp_get_nsapi_linkid(nsapi, &linkid);
          sn_dti_cnf->dti_linkid = linkid;
          sndcp_data->nu->sn_dti_cnf_expected = FALSE;
          sn_dti_cnf->dti_conn = NAS_CONNECT_DTI;

          PSEND(hCommMMI, sn_dti_cnf);
        }
#endif
        nu_unitready_ind_if_nec(nsapi);

      } else if (!opened) {
        sndcp_data->nu->connection_is_opened = FALSE;
        sndcp_data->nu->sn_unitready_ind_pending = FALSE;
        sndcp_data->nu->sn_switch_cnf_expected = FALSE;
      }
      break;
    case NU_ACK_SUA_RECEPTIVE:
    case NU_ACK_SUA_NOT_RECEPTIVE:
    case NU_SUS_SUA_RECEPTIVE:
    case NU_SUS_SUA_NOT_RECEPTIVE:
    case NU_REC_SUA_NOT_RECEPTIVE:
#ifndef NCONFIG
    case NU_SEND_ACK_SUA_RECEPTIVE:
    case NU_SEND_ACK_SUA_NOT_RECEPTIVE:
    case NU_SEND_SUS_SUA_RECEPTIVE:
    case NU_SEND_SUS_SUA_NOT_RECEPTIVE:
    case NU_SEND_REC_SUA_NOT_RECEPTIVE:
#endif /* NCONFIG */
      if (!sndcp_data->nu->connection_is_opened
          &&
          opened) {
        sndcp_data->nu->connection_is_opened = TRUE;
#ifdef SNDCP_UPM_INCLUDED
        {
          U32 linkid = 0;
          PALLOC (sn_dti_cnf, SN_DTI_CNF);
          sndcp_get_nsapi_linkid(nsapi, &linkid);
          sn_dti_cnf->dti_linkid = linkid;
          sndcp_data->nu->sn_dti_cnf_expected = FALSE;
          sn_dti_cnf->dti_conn = NAS_CONNECT_DTI;

          PSEND(hCommMMI, sn_dti_cnf);
        }
        
#else 
        if (sndcp_data->nu->sn_switch_cnf_expected) {
          PALLOC (sn_switch_cnf, SN_SWITCH_CNF);
          sn_switch_cnf->nsapi = nsapi;
          sndcp_data->nu->sn_switch_cnf_expected = FALSE;
          PSEND(hCommMMI, sn_switch_cnf);
        }
#endif
        nu_ready_ind_if_nec(nsapi);
      } else if (!opened) {
        sndcp_data->nu->connection_is_opened = FALSE;
        sndcp_data->nu->sn_ready_ind_pending = FALSE;
        sndcp_data->nu->sn_switch_cnf_expected = FALSE;
      }
      break;
    default:
      TRACE_ERROR( "Function nu_connection_state unexpected" );
      break;
  }
} /* nu_connection_state() */

/*
+------------------------------------------------------------------------------
| Function    : nu_sn_data_req
+------------------------------------------------------------------------------
| Description : Handles the primitive SN_DATA_REQ
|
| Parameters  : *sn_data_req - Ptr to primitive payload
|
+------------------------------------------------------------------------------
*/
GLOBAL void nu_sn_data_req ( T_SN_DATA_REQ *sn_data_req )
{
  BOOL used = FALSE;
  BOOL sack = FALSE;
  UBYTE sapi = 0;

  TRACE_FUNCTION( "nu_sn_data_req" );

  dti_stop(sndcp_data->hDTI,
           0,
#ifndef SNDCP_UPM_INCLUDED
           SNDCP_INTERFACE_ACK,
#else
           SNDCP_INTERFACE_UNACK,
#endif
           sn_data_req->nsapi);

  /*
   * set service instance according to nsapi in primitive
   */
  sndcp_data->nu = & sndcp_data->nu_base[sn_data_req->nsapi];
  /*
   * User has used up his ready_ind.
   */
  sndcp_data->nu->sn_ready_ind_pending = FALSE;
  /*
   * If context is not active, discard primitive.
   */
  sndcp_is_nsapi_used(sn_data_req->nsapi, &used);
  if (!used && sn_data_req != NULL) {
    MFREE_PRIM(sn_data_req);  
    sn_data_req = NULL;
    return;
  }
  if (sn_data_req == NULL) {
    /*
     * Should not be possible. Only included to avoid NULL pointer use.
     */
    return;
  }

#ifdef SNDCP_TRACE_IP_DATAGRAM
  if(sndcp_data->trace_ip_header || sndcp_data->trace_ip_datagram){
    TRACE_EVENT("--------- Uplink IP datagram ---------");
#ifdef _SNDCP_DTI_2_
    sndcp_trace_ip_datagram(& sn_data_req->desc_list2);
#else /*_SNDCP_DTI_2_*/
    sndcp_trace_ip_datagram(& sn_data_req->desc_list);
#endif /*_SNDCP_DTI_2_*/
    TRACE_EVENT("--------------------------------------");
  } else {
#ifdef _SNDCP_DTI_2_
    sndcp_default_ip_trace(& sn_data_req->desc_list2, SNDCP_UL_PACKET);
#else /*_SNDCP_DTI_2_*/
    sndcp_default_ip_trace& sn_data_req->desc_list, SNDCP_UL_PACKET);
#endif /*_SNDCP_DTI_2_*/
  }
  if(sndcp_data->trace_ip_bin){
#ifdef _SNDCP_DTI_2_
    sndcp_bin_trace_ip(& sn_data_req->desc_list2, SNDCP_UL_PACKET);
#else /*_SNDCP_DTI_2_*/
    sndcp_bin_trace_ip(& sn_data_req->desc_list, SNDCP_UL_PACKET);
#endif /*_SNDCP_DTI_2_*/
  }

#else /* SNDCP_TRACE_IP_DATAGRAM */

#ifdef SNDCP_TRACE_BUFFER
#ifdef _SNDCP_DTI_2_
  TRACE_EVENT_P1("uplink at SN SAP: %d octets",
                 sn_data_req->desc_list2.list_len);
  sndcp_trace_desc_list(& sn_data_req->desc_list2);
#else /*_SNDCP_DTI_2_*/
  TRACE_EVENT_P1("uplink at SN SAP: %d octets",
                 sn_data_req->desc_list.list_len);
  sndcp_trace_desc_list(& sn_data_req->desc_list);
#endif /*_SNDCP_DTI_2_*/
#endif /* SNDCP_TRACE_BUFFER */
#endif /* SNDCP_TRACE_IP_DATAGRAM */


  switch( GET_STATE( NU ) )
  {
    case NU_ACK_SUA_RECEPTIVE:
      /*
       * Buffer the given N-PDU
       */
      nu_buffer_npdu(sndcp_data->nu->send_npdu_number_ack, sn_data_req);
      /*
       * It is not checked here if the nsapi is active anyway!
       */
      sndcp_get_nsapi_sapi(sndcp_data->nu->nsapi, &sapi);
      SET_STATE(NU, NU_ACK_SUA_NOT_RECEPTIVE);
      sndcp_data->nu->send_npdu_number_ack =
        (U8)((sndcp_data->nu->send_npdu_number_ack + 1) % MAX_NPDU_NUMBER_ACK);
      sndcp_get_sapi_ack(sapi, &sack);
      if(sack){
        sig_nu_sua_data_req(sn_data_req,
                            (U8)((sndcp_data->nu->send_npdu_number_ack - 1
                            + MAX_NPDU_NUMBER_ACK)% MAX_NPDU_NUMBER_ACK),
                            sn_data_req->nsapi,
                            sapi);
      }


      break;
    case NU_UNACK_SU_NOT_RECEPTIVE:
    case NU_UNACK_SU_RECEPTIVE:
      nu_unitready_ind_if_nec(sn_data_req->nsapi);
#ifdef _SNDCP_DTI_2_
      MFREE_PRIM(sn_data_req);
#else /*_SNDCP_DTI_2_*/
      PFREE_DESC(sn_data_req);
#endif /*_SNDCP_DTI_2_*/
      sn_data_req = NULL;
      break;
    case NU_REC_SUA_NOT_RECEPTIVE:
    case NU_SUS_SUA_NOT_RECEPTIVE:
    case NU_SUS_SUA_RECEPTIVE:
    case NU_ACK_SUA_NOT_RECEPTIVE:

      nu_buffer_npdu(sndcp_data->nu->send_npdu_number_ack,
                     sn_data_req);
      sndcp_data->nu->send_npdu_number_ack =
        (U8)((sndcp_data->nu->send_npdu_number_ack + 1) % MAX_NPDU_NUMBER_ACK);
      break;
#ifndef NCONFIG
    case NU_SEND_UNACK_SU_RECEPTIVE:
    case NU_SEND_UNACK_SU_NOT_RECEPTIVE:
    case NU_SEND_ACK_SUA_RECEPTIVE:
    case NU_SEND_ACK_SUA_NOT_RECEPTIVE:
    case NU_SEND_SUS_SUA_RECEPTIVE:
    case NU_SEND_SUS_SUA_NOT_RECEPTIVE:
    case NU_SEND_REC_SUA_NOT_RECEPTIVE:
#ifndef SNDCP_UPM_INCLUDED
    dti_start(sndcp_data->hDTI, 0, SNDCP_INTERFACE_ACK, sn_data_req->nsapi);
#ifdef _SNDCP_DTI_2_
    MFREE_PRIM(sn_data_req);
#else /*_SNDCP_DTI_2_*/
    PFREE_DESC(sn_data_req);
#endif /*_SNDCP_DTI_2_*/
#else /*#ifndef SNDCP_UPM_INCLUDED*/
    dti_start(sndcp_data->hDTI, 0, SNDCP_INTERFACE_UNACK, sn_data_req->nsapi);
    MFREE_PRIM(sn_data_req);
#endif /*#ifndef  SNDCP_UPM_INCLUDED*/

      sn_data_req = NULL;
      break;
#endif
    default:
      TRACE_ERROR( "SN_DATA_REQ unexpected" );
#ifdef _SNDCP_DTI_2_
      MFREE_PRIM(sn_data_req);
#else /*_SNDCP_DTI_2_*/
      PFREE_DESC(sn_data_req);
#endif /*_SNDCP_DTI_2_*/
      sn_data_req = NULL;
      break;
  }

} /* nu_sn_data_req() */

/*
+------------------------------------------------------------------------------
| Function    : nu_sn_unitdata_req
+------------------------------------------------------------------------------
| Description : Handles the primitive SN_UNITDATA_REQ
|
| Parameters  : *sn_unitdata_req - Ptr to primitive payload
|
+------------------------------------------------------------------------------
*/
GLOBAL void nu_sn_unitdata_req ( T_SN_UNITDATA_REQ *sn_unitdata_req )
{
  UBYTE sapi = 0;
  BOOL used = FALSE;
  UBYTE nsapi = sn_unitdata_req->nsapi;


#ifdef FLOW_TRACE
  sndcp_trace_flow_control(FLOW_TRACE_SNDCP, FLOW_TRACE_UP, FLOW_TRACE_TOP, FALSE);
#endif

  TRACE_FUNCTION( "nu_sn_unitdata_req" );

     dti_stop(sndcp_data->hDTI,
              0,
              SNDCP_INTERFACE_UNACK,
              sn_unitdata_req->nsapi);

 /*
  * set service instance according to nsapi in primitive
  */
  sndcp_data->nu = & sndcp_data->nu_base[sn_unitdata_req->nsapi];
  /*
   * User has used up his ready_ind.
   */
  sndcp_data->nu->sn_unitready_ind_pending = FALSE;
  /*
   * If context is not active, discard primitive.
   */
  sndcp_is_nsapi_used(sn_unitdata_req->nsapi, &used);
  if (!used) {
#ifdef _SNDCP_DTI_2_
    MFREE_PRIM (sn_unitdata_req);
#else /*_SNDCP_DTI_2_*/
    PFREE_DESC (sn_unitdata_req);
#endif /*_SNDCP_DTI_2_*/
    sn_unitdata_req = NULL;
    return;
  }

#ifdef SNDCP_TRACE_IP_DATAGRAM
  if(sndcp_data->trace_ip_header || sndcp_data->trace_ip_datagram){
    TRACE_EVENT("--------- Uplink IP datagram ---------");
#ifdef _SNDCP_DTI_2_
    sndcp_trace_ip_datagram(& sn_unitdata_req->desc_list2);
#else /*_SNDCP_DTI_2_*/
    sndcp_trace_ip_datagram(& sn_unitdata_req->desc_list);
#endif /*_SNDCP_DTI_2_*/
    TRACE_EVENT("--------------------------------------");
  } else {
#ifdef _SNDCP_DTI_2_
    sndcp_default_ip_trace(& sn_unitdata_req->desc_list2, SNDCP_UL_PACKET);  
#else /*_SNDCP_DTI_2_*/
    sndcp_default_ip_trace(& sn_unitdata_req->desc_list, SNDCP_UL_PACKET);
#endif /*_SNDCP_DTI_2_*/
  }
  if(sndcp_data->trace_ip_bin){
#ifdef _SNDCP_DTI_2_
    sndcp_bin_trace_ip(& sn_unitdata_req->desc_list2, SNDCP_UL_PACKET);
#else /*_SNDCP_DTI_2_*/
    sndcp_bin_trace_ip(& sn_unitdata_req->desc_list, SNDCP_UL_PACKET);
#endif /*_SNDCP_DTI_2_*/
  } 
#else /* SNDCP_TRACE_IP_DATAGRAM */

#ifdef SNDCP_TRACE_BUFFER
#ifdef _SNDCP_DTI_2_
  TRACE_EVENT_P1("uplink at SN SAP: %d octets",
                 sn_unitdata_req->desc_list2.list_len);
  sndcp_trace_desc_list(& sn_unitdata_req->desc_list2);
#else /*_SNDCP_DTI_2_*/
  TRACE_EVENT_P1("uplink at SN SAP: %d octets",
                 sn_unitdata_req->desc_list.list_len);
  sndcp_trace_desc_list(& sn_unitdata_req->desc_list);
#endif /*_SNDCP_DTI_2_*/
#endif /* SNDCP_TRACE_BUFFER */
#endif /* SNDCP_TRACE_IP_DATAGRAM */

  switch( GET_STATE( NU ) )
  {
    case NU_ACK_SUA_NOT_RECEPTIVE:
    case NU_ACK_SUA_RECEPTIVE:
      if (sn_unitdata_req != NULL) {
#ifdef _SNDCP_DTI_2_
        MFREE_PRIM (sn_unitdata_req);
#else /*_SNDCP_DTI_2_*/
        PFREE_DESC(sn_unitdata_req);
#endif /*_SNDCP_DTI_2_*/
        sn_unitdata_req = NULL;
      }
      nu_ready_ind_if_nec(nsapi);
      break;
    case NU_UNACK_SU_NOT_RECEPTIVE:
      if (sn_unitdata_req != NULL) {
#ifdef _SNDCP_DTI_2_
        MFREE_PRIM (sn_unitdata_req);
#else /*_SNDCP_DTI_2_*/
        PFREE_DESC(sn_unitdata_req);
#endif /*_SNDCP_DTI_2_*/
        sn_unitdata_req = NULL;
      }
     break;
    case NU_UNACK_SU_RECEPTIVE:
      /*
       * It is not checked here if the nsapi is active anyway!
       */
      sndcp_get_nsapi_sapi(sndcp_data->nu->nsapi, &sapi);
      SET_STATE(NU, NU_UNACK_SU_NOT_RECEPTIVE);
      sndcp_data->nu->send_npdu_number_unack =
        (sndcp_data->nu->send_npdu_number_unack + 1) % MAX_NPDU_NUMBER_UNACK;
      sig_nu_su_unitdata_req(sn_unitdata_req,
                             (U16)((sndcp_data->nu->send_npdu_number_unack - 1
                             + MAX_NPDU_NUMBER_UNACK) % MAX_NPDU_NUMBER_UNACK),
                             sndcp_data->nu->nsapi,
                             sapi);


      break;
#ifndef NCONFIG
    case NU_SEND_UNACK_SU_RECEPTIVE:
    case NU_SEND_UNACK_SU_NOT_RECEPTIVE:
    case NU_SEND_ACK_SUA_RECEPTIVE:
    case NU_SEND_ACK_SUA_NOT_RECEPTIVE:
    case NU_SEND_SUS_SUA_RECEPTIVE:
    case NU_SEND_SUS_SUA_NOT_RECEPTIVE:
    case NU_SEND_REC_SUA_NOT_RECEPTIVE:
      dti_start(sndcp_data->hDTI, 0, SNDCP_INTERFACE_UNACK, sn_unitdata_req->nsapi);
      if (sn_unitdata_req != NULL) {
#ifdef _SNDCP_DTI_2_
        MFREE_PRIM (sn_unitdata_req);
#else /*_SNDCP_DTI_2_*/
        PFREE_DESC(sn_unitdata_req);
#endif /*_SNDCP_DTI_2_*/
        sn_unitdata_req = NULL;
      }

      break;
#endif
    default:
      TRACE_ERROR( "SN_UNITDATA_REQ unexpected" );
#ifdef _SNDCP_DTI_2_
      MFREE_PRIM (sn_unitdata_req);
#else /*_SNDCP_DTI_2_*/
      PFREE_DESC(sn_unitdata_req);
#endif /*_SNDCP_DTI_2_*/

      sn_unitdata_req = NULL;
      break;
  }

} /* nu_sn_unitdata_req() */