diff src/g23m-gprs/sm/sm_dispatch_message.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/sm/sm_dispatch_message.c	Thu Oct 13 04:24:13 2016 +0000
@@ -0,0 +1,261 @@
+/*----------------------------------------------------------------------------
+|  Project :  3G PS
+|  Module  :  SM
++-----------------------------------------------------------------------------
+|             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 dispatcher for incoming
+|             air interface messages in the Session Management (SM) entity.
+|             For design details, see:
+|             8010.908 SM Detailed Specification
++---------------------------------------------------------------------------*/
+
+/*==== DECLARATION CONTROL =================================================*/
+
+/*==== INCLUDES =============================================================*/
+
+#include "sm.h"
+#include "ccdapi.h"
+
+#include "sm_network_control.h"
+#include "sm_aci_output_handler.h"
+#include "sm_mm_output_handler.h"
+
+/*==== CONSTS ===============================================================*/
+
+/*==== TYPES ================================================================*/
+
+/*==== LOCALS ===============================================================*/
+
+/*==== PRIVATE FUNCTIONS ====================================================*/
+
+/*==== PUBLIC FUNCTIONS =====================================================*/
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_disp_mmpm_unitdata_ind
++------------------------------------------------------------------------------
+| Description : Dispatch MMPM_UNITDATA_IND
+|
+| Parameters  : prim        - received primitive
++------------------------------------------------------------------------------
+*/
+void sm_disp_mmpm_unitdata_ind(T_MMPM_UNITDATA_IND *prim)
+{
+  U8                        ti, ti_flag, msg_type, *msg, ccdResult;
+  U16                       offset;
+  struct T_SM_CONTEXT_DATA *context;
+  T_CAUSE_ps_cause          cause;
+
+  (void)TRACE_FUNCTION("sm_disp_mmpm_unitdata_ind");
+
+  offset     = (U16)(prim->sdu.o_buf + 7) >> 3; /* Offset in octets/bytes in message buffer */
+  msg        = &prim->sdu.buf[offset];
+
+  /* Read L3 header: First TI/PD octet */
+  ti_flag    = (msg[0] & SM_TI_FLAG) == (U8)0 ? (U8)SM_TI_FLAG : (U8)0;
+  ti         = (msg[0] >> 4) & SM_TI_NON_EXT_MASK;
+
+  /* Check for extended TI: If TI == 7, read next octet for real TI */
+  if (ti == (U8)SM_TI_EXTEND_VALUE) {
+    ti       = msg[1]; /* Read real TI from next octet in message */
+
+    if ((ti & (U8)SM_TI_FLAG) == (U8)0) {
+      /* Messages with TI EXT bit = 0 shall be ignored: [3G 24.008, 8.3.2] */
+      (void)TRACE_ERROR("Warning: TI EXT bit = 0 in message - message ignored!");
+      return;
+    } else {
+      ti    &= SM_TI_MASK;
+    }
+    offset   = (U16)16; /* # bits to advance message pointer to reach message type */
+    msg_type = msg[2]; /* Get message type octet after TI */
+    (void)TRACE_EVENT_P1("  Extended TI found: 0x%02x", ti);
+  } else {
+    offset   = (U16)8;  /* # bits to advance message pointer to reach message type */
+    (void)TRACE_EVENT_P1("  Non-extended TI found: 0x%02x", ti);
+    msg_type = msg[1]; /* Get message type octet after TI */
+  }
+  /* Set highest bit iff the direction flag bit was set above */
+  ti |= ti_flag;
+  /* Advance message pointer past TI/PD octet(s) */
+  prim->sdu.l_buf -= offset;
+  prim->sdu.o_buf += offset;
+
+  /* Check for message too short: [3G 24.008, 8.2] */
+  if (prim->sdu.l_buf < (U16)8) {
+    (void)TRACE_ERROR("Warning! Message too short - discarded...");
+    return;
+  }
+
+  /* Find context with TI = ti, if already active/being activated */
+  context = sm_get_context_data_from_ti(ti);
+
+  switch (msg_type) {
+  case ACTIVATE_PDP_CONTEXT_ACCEPT:
+  case ACTIVATE_PDP_CONTEXT_REJECT:
+  case ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT:
+  case ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT:
+  case D_MODIFY_PDP_CONTEXT_REQUEST:
+  case D_MODIFY_PDP_CONTEXT_ACCEPT:
+  case MODIFY_PDP_CONTEXT_REJECT:
+  case DEACTIVATE_PDP_CONTEXT_REQUEST:
+  case DEACTIVATE_PDP_CONTEXT_ACCEPT:
+    if (context == NULL) {
+      /* Message received on TI not relating to an active context, or context
+       * being activated/deactivated: [3G 24.008, 8.3.2 b)]*/
+      (void)TRACE_ERROR("Message received on TI not relating to an active context, or context being activated/deactivated");
+      cause.ctrl_value       = CAUSE_is_from_nwsm;
+      cause.value.nwsm_cause = (U16)CAUSE_NWSM_INVALID_TI;
+      send_msg_sm_status(ti, &cause);
+      return;
+    }
+    break;
+  case REQUEST_PDP_CONTEXT_ACTIVATION:
+    if (ti_flag == (U8)0) {
+      /* Ignore REQUEST PDP CONTEXT ACTIVATION msg with TI flag = 1 [3G 24.008, 8.3.2 c)] */
+      /* Note: flag bit is inverted above! */
+      (void)TRACE_EVENT("REQUEST PDP CONTEXT ACTIVATION msg with TI flag = 1 ignored...");
+      return;
+    }
+    if (context == NULL) {
+      /* If no context exists for the TI, create one. */
+      context = sm_insert_mt_context_data(ti);
+    }
+    break;
+  case SM_STATUS:
+    if (context == NULL) {
+      /* Silently ignore message */
+      return;
+    }
+    break;
+  case ACTIVATE_PDP_CONTEXT_REQUEST:             /* FALL-THROUGH */
+  case ACTIVATE_SECONDARY_PDP_CONTEXT_REQUEST:   /* FALL-THROUGH */
+  case REQUEST_PDP_CONTEXT_ACTIVATION_REJECT:    /* FALL-THROUGH */
+  case U_MODIFY_PDP_CONTEXT_REQUEST:             /* FALL-THROUGH */
+  case U_MODIFY_PDP_CONTEXT_ACCEPT:              /* FALL-THROUGH */
+  default:
+    /* Message type not defined for the PD in the given direction: [3G 24.008, 8.4] */
+    (void)TRACE_ERROR("Message type not defined for the PD in the given direction");
+    cause.ctrl_value       = CAUSE_is_from_nwsm;
+    cause.value.nwsm_cause = (U16)CAUSE_NWSM_MSG_TYPE_NOT_IMPLEMENTED;
+    send_msg_sm_status(ti, &cause);
+    return;
+  } /* switch */
+
+  TRACE_ASSERT(context != NULL);
+
+  /* Decode message */
+  ccdResult = ccd_decodeMsg((U8)CCDENT_SM,
+			    (U8)DOWNLINK,
+			    (T_MSGBUF *)&prim->sdu,
+			    (UBYTE *) _decodedMsg,
+			    (U8)NOT_PRESENT_8BIT);
+
+  if (ccdResult != (U8)ccdOK) {
+    /* Error Handling */
+    U16    parlist[6];
+    U8     first_err;
+    U8     ccd_err;
+
+    /* clear parlist */
+    memset (parlist, 0, sizeof (parlist));
+    first_err = ccd_getFirstError((U8)CCDENT_SM, parlist);
+
+    ccd_err = first_err;
+    /* Loop over errors in parlist.  Fix inherited from TI Berlin. */
+    do
+    {
+    /* Error Handling */
+    switch (ccd_err) {
+      case ERR_COMPREH_REQUIRED:    /* Comprehension required */
+      case ERR_MAND_ELEM_MISS: {    /* Mandatory elements missing */
+        (void)TRACE_ERROR("CCD ERROR: Mandatory elements missing");
+	if (msg_type == (U8)DEACTIVATE_PDP_CONTEXT_REQUEST) {
+	  /* [3G 24.008, 8.5.5]: If msg_type is DEACTIVATE PDP CONTEXT REQUEST,
+	   * respond with DEACTIVATE PDP CONTEXT ACCEPT and release context. */
+	  send_msg_deactivate_pdp_context_accept(context);
+	} else if (msg_type == (U8)REQUEST_PDP_CONTEXT_ACTIVATION) {
+	  /* [3G 24.008, 8.5.5]: If msg_type is REQUEST PDP CONTEXT ACTIVATION,
+	   * respond with SM STATUS, cause #96 "invalid mandatory information". */
+	  cause.ctrl_value       = CAUSE_is_from_nwsm;
+	  cause.value.nwsm_cause = (U16)CAUSE_NWSM_INVALID_MANDATORY_ELEMENT;
+	  send_msg_sm_status(ti, &cause);
+          return;
+        } else {
+ 	  cause.ctrl_value       = CAUSE_is_from_nwsm;
+	  cause.value.nwsm_cause = (U16)CAUSE_NWSM_INVALID_MANDATORY_ELEMENT;
+	  send_msg_sm_status(ti, &cause);
+          return;
+	}
+        /*@switchbreak@*/
+	break;
+      }
+    } /* switch */
+    ccd_err = ccd_getNextError ((U8)CCDENT_SM, parlist);
+    } while (ccd_err != (U8)ERR_NO_MORE_ERROR);
+  } /* if (ccdResult...) */
+
+  switch (msg_type) {
+  case ACTIVATE_PDP_CONTEXT_ACCEPT:
+    /* Forward to Network Control */
+    sm_network_control(context, SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, _decodedMsg);
+    break;
+  case ACTIVATE_PDP_CONTEXT_REJECT:
+    /* Forward to Network Control */
+    sm_network_control(context, SM_M_ACTIVATE_PDP_CONTEXT_REJECT, _decodedMsg);
+    break;
+  case ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT:
+    /* Forward to Network Control */
+    sm_network_control(context, SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, _decodedMsg);
+    break;
+  case ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT:
+    /* Forward to Network Control */
+    sm_network_control(context, SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, _decodedMsg);
+    break;
+  case REQUEST_PDP_CONTEXT_ACTIVATION:
+    /* Forward to Network Control */
+    sm_network_control(context, SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, _decodedMsg);
+    break;
+  case D_MODIFY_PDP_CONTEXT_REQUEST:
+    /* Forward to Network Control */
+    sm_network_control(context, SM_M_MODIFY_PDP_CONTEXT_REQUEST, _decodedMsg);
+    break;
+  case D_MODIFY_PDP_CONTEXT_ACCEPT:
+    /* Forward to Network Control */
+    sm_network_control(context, SM_M_MODIFY_PDP_CONTEXT_ACCEPT, _decodedMsg);
+    break;
+  case MODIFY_PDP_CONTEXT_REJECT:
+    /* Forward to Network Control */
+    sm_network_control(context, SM_M_MODIFY_PDP_CONTEXT_REJECT, _decodedMsg);
+    break;
+  case DEACTIVATE_PDP_CONTEXT_REQUEST:
+    /* Forward to Network Control */
+    sm_network_control(context, SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, _decodedMsg);
+    break;
+  case DEACTIVATE_PDP_CONTEXT_ACCEPT:
+    /* Forward to Network Control */
+    sm_network_control(context, SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, _decodedMsg);
+    break;
+  case SM_STATUS:
+    /* Forward to Network Control */
+    sm_network_control(context, SM_M_SM_STATUS, _decodedMsg);
+    break;
+  } /* switch */
+
+  /* Deallocate context if it was marked for deactivation by the above operation */
+  /*lint -e613 (Possible use of null pointer 'context' in left argument to operator '->') */
+  if (sm_is_context_pending_deallocation(context)) {
+    sm_free_context_data_by_nsapi(context->nsapi);
+  }
+}
+
+/*==== END OF FILE ==========================================================*/