view src/g23m-gprs/upm/upm_pei.c @ 478:5e39123540e6

hybrid fw: Openmoko-mimicking AT@BAND command implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 14 Jun 2018 06:04:54 +0000
parents 2cf312e56ee7
children
line wrap: on
line source

/*----------------------------------------------------------------------------
|  Project :  3G PS
|  Module  :  UPM
+-----------------------------------------------------------------------------
|             Copyright 2003 Texas Instruments.
|             All rights reserved. 
| 
|             This file is confidential and a trade secret of Texas 
|             Instruments .
|             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. 
+-----------------------------------------------------------------------------
| Purpose:    This module implements the process body interface
|             for the User Plane Manager (UPM) entity.
|             For design details, see:
|             8010.939 UPM Detailed Specification
+---------------------------------------------------------------------------*/

/*==== DECLARATION CONTROL =================================================*/

#ifndef UPM_PEI_C
#define UPM_PEI_C
#endif

/*==== INCLUDES =============================================================*/

#include "upm.h"

#include <pei.h>
#include <custom.h>

#include "upm_dispatcher.h"

#include "mon_upm.h"

/*==== CONSTS ===============================================================*/

/*==== TYPES ================================================================*/

/*==== LOCALS ===============================================================*/

static T_MONITOR upm_mon;
static BOOL first_access = TRUE;

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

/*
+------------------------------------------------------------------------------
| Function              : pei_primitive
+------------------------------------------------------------------------------
| Description   :  This function is called by the frame when a primitive is
|                  received and needs to be processed.
|
|                                 |
|                                 |                                 UPPER LAYER
|                                 v
|  +---------------------------(DTI SAP)--------------------------+
|  |                                                              |
|  |                             UPM                              |
|  |                                                              |
|  +-^---------^---------^---------^--------^---------^---------^-+
|    |         |         |         |        |         |         |
|    |         |         |         |        |         |         |   LOWER LAYER
| (SM SAP) (MMPM SAP) (RR SAP) (RRC SAP) (SN SAP) (PDCP SAP) (MEM SAP)
|
| Parameters  : prim      - Pointer to the received primitive
|
| Return      : PEI_OK    - function succeeded
|               PEI_ERROR - function failed
+------------------------------------------------------------------------------
*/
static short pei_primitive (void *primitive)
     /*@globals upm_data@*/
{
  (void)TRACE_FUNCTION("UPM pei_primitive");

  if (primitive != NULL)
  {
    T_PRIM_HEADER *prim;
    U32 opc;

    opc = P_OPC(primitive);

/*@i1@*/(void)PTRACE_IN (opc);

    prim = (T_PRIM_HEADER *)&((T_PRIM *)primitive)->data;

    /* Memory supervision ? */
    VSI_PPM_RCV (primitive);

    switch (opc)
    {
#ifndef UPM_WITHOUT_USER_PLANE
      /* DTI SAP */
#ifdef DTI2
      case DTI2_CONNECT_REQ:
        upm_disp_dti_connect_req((T_DTI2_CONNECT_REQ *)(prim));
        /* PFREE is called in the DTILIB */
        break;

      case DTI2_CONNECT_CNF:
        upm_disp_dti_connect_cnf ((T_DTI2_CONNECT_CNF *)(prim));
        /* PFREE is called in the DTILIB */
        break;

      case DTI2_CONNECT_IND:
        upm_disp_dti_connect_ind ((T_DTI2_CONNECT_IND *)(prim));
        /* PFREE is called in the DTILIB */
        break;

      case DTI2_CONNECT_RES:
        upm_disp_dti_connect_res((T_DTI2_CONNECT_RES *)(prim));
        /* PFREE is called in the DTILIB */
        break;

      case DTI2_DISCONNECT_IND:
        upm_disp_dti_disconnect_ind((T_DTI2_DISCONNECT_IND *)(prim));
        /* PFREE is called in the DTILIB */
        break;

      case DTI2_DISCONNECT_REQ:
        upm_disp_dti_disconnect_req((T_DTI2_DISCONNECT_REQ *)(prim));
        /* PFREE is called in the DTILIB */
        break;
#endif /* DTI2 */

      case DTI2_GETDATA_REQ:
        upm_disp_dti_getdata_req((T_DTI2_GETDATA_REQ *)(prim));
        /* PFREE is called in the DTILIB */
        break;

      case DTI2_READY_IND:
        upm_disp_dti_ready_ind ((T_DTI2_READY_IND *)(prim));
        /* PFREE is called in the DTILIB */
        break;

      case DTI2_DATA_REQ:
        upm_disp_dti_data_req((T_DTI2_DATA_REQ *)(prim));
        /* PFREE is called in the upm_sig_callback function in upm_dti_handler.c */
        break;

      case DTI2_DATA_IND:
        upm_disp_dti_data_ind ((T_DTI2_DATA_IND *)(prim));
        /* PFREE is called in the upm_sig_callback function in upm_dti_handler.c */
        break;

#ifdef DEBUG
      case DTI2_DATA_TEST_REQ:
        upm_disp_dti_data_test_req((T_DTI2_DATA_TEST_REQ *)(prim));
        /* PFREE is called in the DTILIB */
        break;
      case DTI2_DATA_TEST_IND:
        upm_disp_dti_data_test_ind((T_DTI2_DATA_TEST_IND *)(prim));
        /* PFREE is called in the DTILIB */
        break;
#endif /* DEBUG */

#endif /* UPM_WITHOUT_USER_PLANE */

      /* SM SAP */
      case SM_ACTIVATE_STARTED_IND:
        upm_disp_sm_activate_started_ind((T_SM_ACTIVATE_STARTED_IND *)(prim));
        PFREE(prim);
        break;

      case SM_ACTIVATE_IND:
        upm_disp_sm_activate_ind((T_SM_ACTIVATE_IND *)(prim));
        PFREE(prim);
        break;

      case SM_DEACTIVATE_IND:
        upm_link_dispatch_sm_deactivate_ind((T_SM_DEACTIVATE_IND *)(prim));
        PFREE(prim);
        break;

      case SM_MODIFY_IND:
        upm_disp_sm_modify_ind((T_SM_MODIFY_IND *)(prim));
        PFREE(prim);
        break;

#ifndef UPM_WITHOUT_USER_PLANE
      /* MMPM SAP */
      case MMPM_SUSPEND_IND:
        upm_disp_mmpm_suspend_ind((T_MMPM_SUSPEND_IND *)(prim));
        PFREE(prim);
        break;

      case MMPM_RESUME_IND:
        upm_disp_mmpm_resume_ind((T_MMPM_RESUME_IND *)(prim));
        PFREE(prim);
        break;
#endif /* UPM_WITHOUT_USER_PLANE */

#ifdef TI_UMTS
      case MMPM_REESTABLISH_CNF:
        upm_disp_mmpm_reestablish_cnf((T_MMPM_REESTABLISH_CNF *)(prim));
        PFREE(prim);
        break;

      case MMPM_REESTABLISH_REJ:
        upm_disp_mmpm_reestablish_rej((T_MMPM_REESTABLISH_REJ *)(prim));
        PFREE(prim);
        break;
#endif /* TI_UMTS */
#ifdef TI_GPRS
      case MMPM_SEQUENCE_IND:
        upm_disp_mmpm_sequence_ind((T_MMPM_SEQUENCE_IND *)(prim));
        PFREE(prim);
        break;
#endif /* TI_GPRS */
#ifdef TI_DUAL_MODE
      case MMPM_RAT_CHANGE_COMPLETED_IND:
        upm_disp_mmpm_rat_change_completed_ind((T_MMPM_RAT_CHANGE_COMPLETED_IND *)(prim));
        PFREE(prim);
        break;

      case MMPM_RAT_CHANGE_IND:
        upm_disp_mmpm_rat_change_ind((T_MMPM_RAT_CHANGE_IND *)(prim));
        PFREE(prim);
        break;
#endif /* TI_DUAL_MODE */

#ifdef TI_UMTS
      /* PDCP SAP */
      case PDCP_DATA_IND:
        upm_disp_pdcp_data_ind((T_PDCP_DATA_IND *)(prim));
        PFREE(prim);
        break;

#ifdef DEBUG
      case PDCP_TEST_DATA_IND:
        upm_disp_pdcp_test_data_ind((T_PDCP_TEST_DATA_IND *)(prim));
        PFREE(prim);
        break;
#endif /* DEBUG */

#ifdef TI_DUAL_MODE
      case PDCP_AM_GET_PENDING_PDU_CNF:
        upm_disp_pdcp_get_pending_pdu_cnf((T_PDCP_AM_GET_PENDING_PDU_CNF *)(prim));
        PFREE(prim);
        break;

#ifdef DEBUG
      case PDCP_TEST_AM_GET_PENDING_PDU_CNF:
        upm_disp_pdcp_test_am_get_pending_pdu_cnf((T_PDCP_TEST_AM_GET_PENDING_PDU_CNF *)(prim));
        PFREE(prim);
        break;
#endif

      /* RRC SAP */
      case RRC_MOVE_USER_DATA_IND:
        upm_disp_rrc_move_user_data_ind((T_RRC_MOVE_USER_DATA_IND *)(prim));
        PFREE(prim);
        break;
#endif /* TI_DUAL_MODE */
      case RRC_RAB_ESTABLISH_IND:
        upm_disp_rrc_rab_establish_ind((T_RRC_RAB_ESTABLISH_IND *)(prim));
        PFREE(prim);
        break;
      case RRC_RAB_ESTABLISH_COMPLETE_IND:
        upm_disp_rrc_rab_establish_complete_ind((T_RRC_RAB_ESTABLISH_COMPLETE_IND *)(prim));
        PFREE(prim);
        break;
      case RRC_RAB_RELEASE_IND:
        upm_disp_rrc_rab_release_ind((T_RRC_RAB_RELEASE_IND *)(prim));
        PFREE(prim);
        break;

      /* MEM SAP */
      case MEM_READY_IND:
        upm_disp_mem_ready_ind((T_MEM_READY_IND *)(prim));
        PFREE(prim);
        break;
#endif /* TI_UMTS */

#ifdef TI_GPRS
      /* SN SAP */
      case SN_ACTIVATE_CNF:
        upm_disp_sn_activate_cnf((T_SN_ACTIVATE_CNF *)(prim));
        PFREE(prim);
        break;

      case SN_COUNT_CNF:
        upm_disp_sn_count_cnf((T_SN_COUNT_CNF *)(prim));
        PFREE(prim);
        break;

      case SN_MODIFY_CNF:
        upm_disp_sn_modify_cnf((T_SN_MODIFY_CNF *)(prim));
        PFREE(prim);
        break;

      case SN_DEACTIVATE_CNF:
        upm_disp_sn_deactivate_cnf((T_SN_DEACTIVATE_CNF *)(prim));
        PFREE(prim);
        break;

      case SN_STATUS_IND:
        /* May affect multiple contexts.  Special dispatch handling. */
        upm_sndcp_dispatch_sn_status_ind((T_SN_STATUS_IND *)(prim));
        PFREE(prim);
        break;

      case SN_SEQUENCE_CNF:
        /* May affect multiple contexts.  Special dispatch handling. */
        upm_sndcp_dispatch_sn_sequence_cnf((T_SN_SEQUENCE_CNF *)(prim));
        PFREE(prim);
        break;

#ifdef TI_DUAL_MODE
      case SN_GET_PENDING_PDU_CNF:
        upm_disp_sn_get_pending_pdu_cnf((T_SN_GET_PENDING_PDU_CNF *)(prim));
        PFREE(prim);
        break;

#ifdef DEBUG
      case SN_TEST_GET_PENDING_PDU_CNF:
        upm_disp_sn_test_get_pending_pdu_cnf((T_SN_TEST_GET_PENDING_PDU_CNF *)(prim));
        PFREE(prim);
        break;
#endif /* DEBUG */

      /* RR SAP */
      case RR_MOVE_USER_DATA_IND:
        upm_disp_rr_move_user_data_ind((T_RR_MOVE_USER_DATA_IND *)(prim));
        PFREE(prim);
        break;
#endif /* TI_DUAL_MODE */
#endif /* TI_GPRS */

      /* UPM SAP */
      case UPM_COUNT_REQ:
        upm_disp_upm_count_req((T_UPM_COUNT_REQ *)(prim));
        PFREE(prim);
        break;

#ifndef UPM_WITHOUT_USER_PLANE
      case UPM_DTI_REQ:
        upm_disp_upm_dti_req((T_UPM_DTI_REQ *)(prim));
        PFREE(prim);
        break;
#endif /* UPM_WITHOUT_USER_PLANE */

      default:
        /* forward sys primitives to the environment */
        if ( (opc & SYS_MASK) != 0) {
          (void)vsi_c_primitive(VSI_CALLER primitive);
          return (short)PEI_OK;
        } else {
          PFREE(prim);
          return (short)PEI_ERROR;
        }
    } /* switch */
  } /* if (prim != NULL) */

  return PEI_OK;
}

/*
+------------------------------------------------------------------------------
| Function      : pei_init
+------------------------------------------------------------------------------
| Description   : This function is called by the frame. It is used
|                 to initialise the entity.
|
| Parameters    : handle            - task handle
|
| Return        : PEI_OK            - entity initialised
|                 PEI_ERROR         - entity not (yet) initialised
+------------------------------------------------------------------------------
*/
static short pei_init (T_HANDLE handle)
  /*@globals undef upm_data@*/
  /*@modifies upm_data@*/
{
  (void)TRACE_FUNCTION ("UPM pei_init");

  /* Clear static entity data store */
  memset(&upm_data, 0, sizeof(upm_data));

  /*
   * Initialize task handles
   */
  upm_data.upm_handle = handle;
  hCommACI   = VSI_ERROR;
  hCommSM    = VSI_ERROR;
  hCommMM    = VSI_ERROR;
#ifdef TI_UMTS
  hCommPDCP  = VSI_ERROR;
  hCommRRC   = VSI_ERROR;
#endif /* TI_UMTS */
#ifdef TI_GPRS
  hCommSNDCP = VSI_ERROR;
  hCommRR    = VSI_ERROR;
#endif /* TI_GPRS */

  /*
   * Open communication channels
   */
  if (hCommACI < VSI_OK)
  {
    if ((hCommACI = vsi_c_open(VSI_CALLER ACI_NAME)) < VSI_OK)
    {
      return (short)PEI_ERROR;
    }
  }

  if (hCommSM < VSI_OK)
  {
    if ((hCommSM = vsi_c_open(VSI_CALLER SM_NAME)) < VSI_OK)
    {
      return (short)PEI_ERROR;
    }
  }

  if (hCommMM < VSI_OK)
  {
/*#ifdef UPM_EDGE */
    if ((hCommMM = vsi_c_open(VSI_CALLER GMM_NAME)) < VSI_OK)
/*#else */ /*#ifdef UPM_EDGE*/
/*    if ((hCommMM = vsi_c_open(VSI_CALLER MM_NAME)) < VSI_OK)
#endif */ /*#ifdef UPM_EDGE*/
    {
      return (short)PEI_ERROR;
    }
  }


#ifdef TI_UMTS
  if (hCommPDCP < VSI_OK)
  {
    if ((hCommPDCP = vsi_c_open(VSI_CALLER PDCP_NAME)) < VSI_OK)
    {
      return (short)PEI_ERROR;
    }
  }

  if (hCommRRC < VSI_OK)
  {
    if ((hCommRRC = vsi_c_open(VSI_CALLER RRC_NAME)) < VSI_OK)
    {
      return (short)PEI_ERROR;
    }
  }
#endif /* TI_UMTS */

#ifdef TI_GPRS
  if (hCommSNDCP < VSI_OK)
  {
    if ((hCommSNDCP = vsi_c_open (VSI_CALLER SNDCP_NAME)) < VSI_OK)
    {
      return (short)PEI_ERROR;
    }
  }

  if (hCommRR < VSI_OK)
  {
    if ((hCommRR = vsi_c_open (VSI_CALLER RR_NAME)) < VSI_OK)
    {
      return (short)PEI_ERROR;
    }
  }
#endif /* TI_GPRS */

  /*
   * Initialize entity data (call init functions)
   */

#ifdef TI_UMTS
  mem_init();
#endif /* TI_UMTS */

  /*
   * Initialize DTI
   */
#ifndef UPM_WITHOUT_USER_PLANE
  assert (upm_hDTI == NULL);
  upm_hDTI = dti_init((U8)NAS_SIZE_NSAPI, upm_data.upm_handle,
                      DTI_DEFAULT_OPTIONS, upm_sig_callback);
#endif /* UPM_WITHOUT_USER_PLANE */

  return (short)PEI_OK;
}

/*
+------------------------------------------------------------------------------
| Function      : pei_exit
+------------------------------------------------------------------------------
| Description   : This function is called by the frame when the entity
|                 is terminated. All open resources are freed.
|
| Parameters    : -
|
| Return        : PEI_OK            - exit sucessful
|                 PEI_ERROR         - exit not successful
+------------------------------------------------------------------------------
*/
static short pei_exit (void)
{
  int nsapi;
  (void)TRACE_FUNCTION ("UPM pei_exit");

  /*
   * Clean up entity data
   */

  for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) {
    struct T_CONTEXT_DATA *ptr_context_data;

    ptr_context_data = upm_get_context_data_from_nsapi(nsapi);
    if (ptr_context_data != NULL) {
#ifdef TI_GPRS
      upm_sndcp_control_exit        (ptr_context_data);
#endif /* TI_GPRS */
#ifdef TI_UMTS
      upm_rab_control_exit          (ptr_context_data);
#endif
      upm_link_control_exit         (ptr_context_data);
#ifndef UPM_WITHOUT_USER_PLANE
      upm_downlink_data_control_exit(ptr_context_data);
      upm_uplink_data_control_exit  (ptr_context_data);
      upm_dti_control_exit          (ptr_context_data);
#endif /* UPM_WITHOUT_USER_PLANE */

#ifdef DEBUG
 #ifdef TI_UMTS
      upm_free_mem_buffer(ptr_context_data);
 #endif
#endif
      upm_free_context_data(nsapi);
    }
  }
#ifdef TI_DUAL_MODE
  upm_rat_control_exit();
#endif

#ifndef UPM_WITHOUT_USER_PLANE
  /*
   * Clean-up DTILIB
   */
  dti_deinit(upm_hDTI);

  /* Disable forced DTI neighbor routing */
#ifdef DEBUG
  upm_disp_force_neighbor(NULL);
#endif
#endif /* UPM_WITHOUT_USER_PLANE */

  /*
   * Close communication channels
   */
  (void)vsi_c_close(VSI_CALLER hCommACI);
  hCommACI   = VSI_ERROR;

  (void)vsi_c_close(VSI_CALLER hCommSM);
  hCommSM    = VSI_ERROR;

  (void)vsi_c_close(VSI_CALLER hCommMM);
  hCommMM    = VSI_ERROR;

#ifdef TI_UMTS
  (void)vsi_c_close(VSI_CALLER hCommPDCP);
  hCommPDCP  = VSI_ERROR;

  (void)vsi_c_close(VSI_CALLER hCommRRC);
  hCommRRC   = VSI_ERROR;
#endif /* TI_UMTS */

#ifdef TI_GPRS
  (void)vsi_c_close(VSI_CALLER hCommSNDCP);
  hCommSNDCP = VSI_ERROR;

  (void)vsi_c_close(VSI_CALLER hCommRR);
  hCommRR    = VSI_ERROR;
#endif /* TI_GPRS */

  return PEI_OK;
}

/*
+------------------------------------------------------------------------------
| Function              : pei_config
+------------------------------------------------------------------------------
| Description   : This function is called by the frame when a primitive is
|                 received indicating dynamic configuration.
|
|                 This function is not used in this entity.
|
| Parameters    :       handle            - Communication handle
|
| Return      : PEI_OK            - sucessful
|               PEI_ERROR         - not successful
+------------------------------------------------------------------------------
*/
static short pei_config (char *inString)
{
#ifdef DEBUG
  const size_t neighbor_strlen = strlen("NEIGHBOR_ENTITY");
#endif
  (void)TRACE_FUNCTION ("UPM pei_config");
  (void)TRACE_FUNCTION (inString);

#ifdef DEBUG

#ifdef TI_UMTS
  if ( strcmp(inString, "MEM_FLOW_CONTROL ON") == 0)
  {
    upm_disp_adjust_mem_flow_control(TRUE);
  }
  else if ( strcmp(inString, "MEM_FLOW_CONTROL OFF") == 0)
  {
    upm_disp_adjust_mem_flow_control(FALSE);
  }
  else if ( strncmp(inString, "NEIGHBOR_ENTITY", neighbor_strlen) == 0)
  {
    if (strncmp(&inString[neighbor_strlen + 1], "CLEAR", sizeof("CLEAR")) != 0)
    {
      upm_disp_force_neighbor(&inString[neighbor_strlen + 1]);
    } else {
      upm_disp_force_neighbor(NULL);
    }
  } else
#endif /* TI_UMTS */
  if ( strcmp(inString, "LL_ENTITY_TEST") == 0)
  {
    upm_activate_ll_entity_test();
  }
#endif /* DEBUG */

  return PEI_OK;
}

/*
+------------------------------------------------------------------------------
| Function      : pei_monitor
+------------------------------------------------------------------------------
| Description   : This function is called by the frame in case sudden entity
|                 specific data is requested (e.g. entity Version).
|
| Parameters    :  out_monitor       - return the address of the data to be
|                                      monitoredCommunication handle
|
| Return        :  PEI_OK            - sucessful (address in out_monitor is valid)
|                  PEI_ERROR         - not successful
+------------------------------------------------------------------------------
*/
/*@-compdef@*/ /*@-mods@*/
static short pei_monitor (void **out_monitor) /*@globals undef upm_mon@*/
{
  (void)TRACE_FUNCTION ("UPM pei_monitor");

  /*
   * Version = "0.S" (S = Step).
   */
  upm_mon.version = "UPM 0.1";
  *out_monitor = &upm_mon;

  return PEI_OK;
}
/*@=compdef@*/ /*@=mods@*/

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

/*
+------------------------------------------------------------------------------
| Function              : pei_create
+------------------------------------------------------------------------------
| Description   :  This function is called by the frame when the process is 
|                  created.
|
| Parameters    :  out_name          - Pointer to the buffer in which to locate
|                                      the name of this entity
|
| Return        :  PEI_OK            - entity created successfuly
|                  PEI_ERROR         - entity could not be created
|
+------------------------------------------------------------------------------
*/
short pei_create (T_PEI_INFO **info)
     /*@globals first_access@*/ /*@modifies first_access@*/
{
/*@-nullassign@*/
static T_PEI_INFO pei_info =
              {
/*@i1@*/       UPM_NAME,      /* name */
               {              /* pei-table */
                 pei_init,
                 pei_exit,
                 pei_primitive,
                 NULL,        /* no pei_timeout function */
                 NULL,        /* no pei_signal function */
                 NULL,        /* no pei_run function */
                 pei_config,
                 pei_monitor
               },
               (U32)1024,     /* stack size */
               (U16)20,       /* queue entries */
               (U16)216,      /* priority (1->low, 255->high) */
               (U16)0,        /* number of timers */
               (U8)0x03       /* flags: bit 0   active(0) body/passive(1) */
              };              /*        bit 1   com by copy(0)/reference(1) */
/*@+nullassign@*/

  (void)TRACE_FUNCTION ("UPM pei_create");

  /*
   * Close Resources if open
   */
  if (first_access)
  {
    first_access = FALSE;
  } else {
    (void)pei_exit();
  }

  /*
   * Export startup configuration data
   */
  *info = &pei_info;

  return PEI_OK;
}

/*==== END OF FILE ==========================================================*/