diff src/g23m-gprs/sm/sm.c @ 1:fa8dc04885d8

src/g23m-*: import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:25:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/g23m-gprs/sm/sm.c	Fri Oct 16 06:25:50 2020 +0000
@@ -0,0 +1,580 @@
+/*----------------------------------------------------------------------------
+|  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:    Utility functions implementation in the SM entity.
+|             For design details, see:
+|             8010.908 SM Detailed Specification
++---------------------------------------------------------------------------*/
+
+/*==== DECLARATION CONTROL =================================================*/
+
+/*==== INCLUDES =============================================================*/
+
+#include <stdio.h>
+#include "sm.h"
+
+/*==== CONSTS ===============================================================*/
+
+/*==== TYPES ================================================================*/
+
+/*==== LOCALS ===============================================================*/
+
+/*==== PRIVATE FUNCTIONS ====================================================*/
+
+/*==== PUBLIC FUNCTIONS =====================================================*/
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_nsapi2nsapi_set
++------------------------------------------------------------------------------
+| Description : Returns nsapi_set corresponding to the input NSAPI
+|
+| Parameters  : nsapi               - NSAPI to convert to nsapi_set
++------------------------------------------------------------------------------
+*/
+U16 sm_nsapi2nsapi_set(int /*@alt U8@*/ nsapi)
+{
+  return (U16)(1UL << (U8)nsapi);
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_add_nsapi_to_nsapi_set
++------------------------------------------------------------------------------
+| Description : Returns nsapi_set with nsapi added to it (1 << nsapi).
+|
+| Parameters  : nsapi               - NSAPI to add
+|               nsapi_set           - nsapi_set to which to add NSAPI
++------------------------------------------------------------------------------
+*/
+U16 sm_add_nsapi_to_nsapi_set(int /*@alt U8@*/ nsapi, U16 nsapi_set)
+{
+  return (nsapi_set | sm_nsapi2nsapi_set(nsapi));
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_remove_nsapi_from_nsapi_set
++------------------------------------------------------------------------------
+| Description : Returns nsapi_set with nsapi removed from it (1 << nsapi).
+|
+| Parameters  : nsapi               - NSAPI to remove
+|               nsapi_set           - nsapi_set in which to remove NSAPI
++------------------------------------------------------------------------------
+*/
+U16 sm_remove_nsapi_from_nsapi_set(int /*@alt U8@*/ nsapi, U16 nsapi_set)
+{
+  return (nsapi_set & (0xffff ^ sm_nsapi2nsapi_set(nsapi)));
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_is_nsapi_in_nsapi_set
++------------------------------------------------------------------------------
+| Description : Returns TRUE iff the input NSAPI (converted to nsapi_set) is
+|               set in the input nsapi_set.
+|
+| Parameters  : nsapi               - NSAPI whose presence to check
+|               nsapi_set           - nsapi_set to compare
++------------------------------------------------------------------------------
+*/
+BOOL sm_is_nsapi_in_nsapi_set(int /*@alt U8,U16@*/ nsapi, U16 nsapi_set)
+{
+  return ((nsapi_set & sm_nsapi2nsapi_set(nsapi)) != 0);
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_nsapi_to_index
++------------------------------------------------------------------------------
+| Description : Returns array index corresponding to NSAPI (nsapi - 5)
+|
+| Parameters  : nsapi               - NSAPI value
++------------------------------------------------------------------------------
+*/
+U16 /*@alt int@*/ sm_nsapi_to_index(U16 /*@alt U8,int@*/nsapi)
+{
+  TRACE_ASSERT((T_NAS_nsapi)nsapi >= NAS_NSAPI_5 && nsapi <= NAS_NSAPI_15);
+  return (nsapi - (U16)NAS_NSAPI_5);
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_index_to_nsapi
++------------------------------------------------------------------------------
+| Description : Returns nsapi value corresponding to array index (index + 5)
+|
+| Parameters  : index               - index value
++------------------------------------------------------------------------------
+*/
+U16 /*@alt int@*/ sm_index_to_nsapi(U16 /*@alt U8,int@*/index)
+{
+  TRACE_ASSERT(index < SM_MAX_NSAPI_OFFSET);
+  return (index + (U16)NAS_NSAPI_5);
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_get_pdp_context_status
++------------------------------------------------------------------------------
+| Description : Get the network status of all NSAPIs.  A bit is set in the
+|               nsapi_set, iff the context corresponding to the NSAPI is
+|               not in network state INACTIVE.
+|
+| Parameters  : None
++------------------------------------------------------------------------------
+*/
+U16 sm_get_pdp_context_status(void)
+{
+  return sm_data.sm_context_activation_status;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_get_current_rat
++------------------------------------------------------------------------------
+| Description : Returns the RAT in which SM is currently active
+|
+| Parameters  : None
++------------------------------------------------------------------------------
+*/
+T_PS_rat /*@alt U8@*/sm_get_current_rat(void)
+{
+  return sm_data.sm_current_rat;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_set_current_rat
++------------------------------------------------------------------------------
+| Description : Sets the RAT in which SM is currently active
+|
+| Parameters  : rat                 - Active RAT (GSM / UMTS)
++------------------------------------------------------------------------------
+*/
+void sm_set_current_rat(T_PS_rat rat)
+{
+  if (rat == PS_RAT_GSM || rat == PS_RAT_UMTS_FDD) {
+    sm_data.sm_current_rat = rat;
+  } else {
+    (void)TRACE_ERROR("Tried to set unknown RAT! (This is OK for EDGE)");
+  }
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_get_current_nw_release
++------------------------------------------------------------------------------
+| Description : Returns the core network release of the network in which SM
+|               is currently active
+|
+| Parameters  : None
++------------------------------------------------------------------------------
+*/
+T_PS_sgsn_rel /*@alt U8@*/ sm_get_current_nw_release(void)
+{
+  return sm_data.sm_current_nw_release;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_is_suspended
++------------------------------------------------------------------------------
+| Description : Returns TRUE if SM is suspended, i.e. has received an
+|               MMPM_SUSPEND_IND primitive from MM.
+|
+| Parameters  : None
++------------------------------------------------------------------------------
+*/
+BOOL sm_is_suspended(void)
+{
+  return sm_data.sm_suspended;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_is_attached
++------------------------------------------------------------------------------
+| Description : Returns TRUE if SM is attached, i.e. has received an
+|               MMPM_ATTACH_IND primitive from MM.
+|
+| Parameters  : None
++------------------------------------------------------------------------------
+*/
+BOOL sm_is_attached(void)
+{
+  return sm_data.sm_attached;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_is_secondary
++------------------------------------------------------------------------------
+| Description : Returns TRUE if secondary flag is set for the context.
+|
+| Parameters  : context             - Context data
++------------------------------------------------------------------------------
+*/
+BOOL sm_is_secondary(struct T_SM_CONTEXT_DATA *context)
+{
+  return (context->flags & (U8)SM_CONTEXT_FLAG_SECONDARY_CONTEXT) != (U8)0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_set_secondary
++------------------------------------------------------------------------------
+| Description : Set secondary flag for the input context
+|
+| Parameters  : context             - Context data
++------------------------------------------------------------------------------
+*/
+void sm_set_secondary(struct T_SM_CONTEXT_DATA *context)
+{
+  context->flags |= (U8)SM_CONTEXT_FLAG_SECONDARY_CONTEXT;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_set_started_during_suspend
++------------------------------------------------------------------------------
+| Description : Set started during suspend flag for the context
+|
+| Parameters  : context             - Context data
++------------------------------------------------------------------------------
+*/
+void sm_set_started_during_suspend(struct T_SM_CONTEXT_DATA *context)
+{
+  if (sm_is_suspended()) {
+    context->flags |= (U8)SM_CONTEXT_FLAG_STARTED_DURING_SUSPEND;
+  } else {
+    context->flags &= 0xff ^ (U8)SM_CONTEXT_FLAG_STARTED_DURING_SUSPEND;
+  }
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_clear_started_during_suspend
++------------------------------------------------------------------------------
+| Description : Clear started during suspend flag for the context
+|
+| Parameters  : context             - Context data
++------------------------------------------------------------------------------
+*/
+void sm_clear_started_during_suspend(struct T_SM_CONTEXT_DATA *context)
+{
+  context->flags &= 0xff ^ (U8)SM_CONTEXT_FLAG_STARTED_DURING_SUSPEND;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_is_started_during_suspend
++------------------------------------------------------------------------------
+| Description : Return TRUE if started during suspend flag is set for the
+|               context.
+|
+| Parameters  : context             - Context data
++------------------------------------------------------------------------------
+*/
+BOOL sm_is_started_during_suspend(struct T_SM_CONTEXT_DATA *context)
+{
+  return (context->flags & (U8)SM_CONTEXT_FLAG_STARTED_DURING_SUSPEND) != (U8)0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_mark_context_for_deallocation
++------------------------------------------------------------------------------
+| Description : Set pending deallocation flag for the context
+|
+| Parameters  : context             - Context data
++------------------------------------------------------------------------------
+*/
+void sm_mark_context_for_deallocation(struct T_SM_CONTEXT_DATA *context)
+{
+  context->flags |= (U8)SM_CONTEXT_FLAG_PENDING_DEALLOCATION;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_is_context_pending_deallocation
++------------------------------------------------------------------------------
+| Description : Returns TRUE if pending deallocation flag is set for the context
+|
+| Parameters  : context             - Context data
++------------------------------------------------------------------------------
+*/
+BOOL sm_is_context_pending_deallocation(struct T_SM_CONTEXT_DATA *context)
+{
+  return (context->flags & (U8)SM_CONTEXT_FLAG_PENDING_DEALLOCATION) != (U8)0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_set_context_pending_reactivation
++------------------------------------------------------------------------------
+| Description : Set or clear pending reactivation flag for the context
+|
+| Parameters  : context             - Context data
++------------------------------------------------------------------------------
+*/
+void sm_set_context_pending_reactivation(struct T_SM_CONTEXT_DATA *context, BOOL flag)
+{
+  if (flag)
+  {
+    context->flags |= (U8)(U8)SM_CONTEXT_FLAG_PENDING_REACTIVATION;
+  } else {
+    context->flags &= 0xff ^ (U8)(U8)SM_CONTEXT_FLAG_PENDING_REACTIVATION;
+  }
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_is_context_pending_reactivation
++------------------------------------------------------------------------------
+| Description : Returns TRUE if pending reactivation flag is set for the context
+|
+| Parameters  : context             - Context data
++------------------------------------------------------------------------------
+*/
+BOOL sm_is_context_pending_reactivation(struct T_SM_CONTEXT_DATA *context)
+{
+  return (context->flags & (U8)SM_CONTEXT_FLAG_PENDING_REACTIVATION) != (U8)0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_is_aci_update_required
++------------------------------------------------------------------------------
+| Description : Returns TRUE if one of the flags affecting the SMREG interface
+|               have changed/are set.
+|
+| Parameters  : update_flags        - Update flags
++------------------------------------------------------------------------------
+*/
+BOOL sm_is_aci_update_required(T_SM_UPDATE_FLAGS update_flags)
+{
+  if ((int)(update_flags & SM_UPDATE_QOS)           != 0 ||
+      (int)(update_flags & SM_UPDATE_QOS_DOWNGRADE) != 0 ||
+      (int)(update_flags & SM_UPDATE_ADDRESS)       != 0 ||
+      (int)(update_flags & SM_UPDATE_COMP_PARAMS)   != 0) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_is_user_plane_update_required
++------------------------------------------------------------------------------
+| Description : Returns TRUE if one of the flags affecting the SM interface
+|               have changed/are set.
+|
+| Parameters  : update_flags        - Update flags
++------------------------------------------------------------------------------
+*/
+BOOL sm_is_user_plane_update_required(T_SM_UPDATE_FLAGS update_flags)
+{
+  if ((int)(update_flags & SM_UPDATE_QOS)                 != 0 ||
+      (int)(update_flags & SM_UPDATE_COMP_PARAMS)         != 0 ||
+      (int)(update_flags & SM_UPDATE_SAPI_RADIO_PRIO_PFI) != 0) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_set_pfi_included
++------------------------------------------------------------------------------
+| Description : Set PFI included flag for the context
+|
+| Parameters  : context             - Context data
++------------------------------------------------------------------------------
+*/
+void sm_set_pfi_included(struct T_SM_CONTEXT_DATA *context, BOOL flag)
+{
+  if (flag)
+  {
+    context->flags |= (U8)SM_CONTEXT_FLAG_PFI_PRESENT;
+  } else {
+    context->flags &= 0xff ^ (U8)SM_CONTEXT_FLAG_PFI_PRESENT;
+  }
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_is_pfi_included
++------------------------------------------------------------------------------
+| Description : Return TRUE if PFI included flag is set for the context.
+|
+| Parameters  : context             - Context data
++------------------------------------------------------------------------------
+*/
+BOOL sm_is_pfi_included(struct T_SM_CONTEXT_DATA *context)
+{
+  return (context->flags & (U8)SM_CONTEXT_FLAG_PFI_PRESENT) != (U8)0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_is_llc_sapi_valid
++------------------------------------------------------------------------------
+| Description : Return TRUE if the LLC SAPI provided is valid, FALSE otherwise.
+|
+| Parameters  : llc_sapi            - LLC SAPI
+|               ti                  - TI for context
++------------------------------------------------------------------------------
+*/
+BOOL sm_is_llc_sapi_valid(U8 llc_sapi, U8 ti)
+{
+  /* This check is only valid in non-UMTS-single mode configurations */
+#if !defined(TI_UMTS) || defined(TI_DUAL_MODE)
+  T_CAUSE_ps_cause          cause;
+
+  if ( (llc_sapi == PS_SAPI_3) ||
+       (llc_sapi == PS_SAPI_5) ||
+       (llc_sapi == PS_SAPI_9) ||
+       (llc_sapi == PS_SAPI_11) )
+  {
+    /* LLC SAPI is OK.  Return TRUE. */
+    return TRUE;
+  } else {
+    /* LLC SAPI has a reserved value. Send a status message. */
+    cause.ctrl_value       = CAUSE_is_from_nwsm;
+    cause.value.nwsm_cause = (U16)CAUSE_NWSM_INVALID_MANDATORY_ELEMENT;
+    send_msg_sm_status(ti, &cause);
+    return FALSE;
+  } 
+#else
+  /* In UMTS single mode, this check is disabled */
+  return TRUE;
+#endif
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_set_current_nw_release
++------------------------------------------------------------------------------
+| Description : Sets the core network release of the network in which SM
+|               is currently active
+|
+| Parameters  : sgsn_rel            - Network release (pre-R99 / R99)
++------------------------------------------------------------------------------
+*/
+void sm_set_current_nw_release(T_PS_sgsn_rel sgsn_rel)
+{
+  if (sgsn_rel == PS_SGSN_98_OLDER || sgsn_rel == PS_SGSN_99_ONWARDS) {
+    sm_data.sm_current_nw_release = sgsn_rel;
+  } 
+  else { /*The Berlin way*/
+    /*If SGSN release is unknown set the value to R98*/
+    (void)TRACE_ERROR("Tried to set unknown core network release. \
+                         Setting R97 as default !");
+    sm_data.sm_current_nw_release = PS_SGSN_98_OLDER;
+  }
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_set_aci_cause
++------------------------------------------------------------------------------
+| Description : Sets the cause value for a context. Used during retransmissions
+|               etc.
+|
+| Parameters  : context             - context data
+|               ctrl_cause          - cause originator
+|               cause               - vause value
++------------------------------------------------------------------------------
+*/
+void sm_set_aci_cause(struct T_SM_CONTEXT_DATA *context,
+		  T_CAUSE_ctrl_value ctrl_cause, U16 cause)
+{
+  (void)TRACE_EVENT_P2("sm_set_aci_cause(ctrl=%d, cause=%04x)", (int)ctrl_cause, cause);
+  TRACE_ASSERT(context != NULL);
+  /*lint -e613 (Possible use of null pointer 'context' in left argument to operator '->') */
+  context->aci_cause.ctrl_value       = ctrl_cause;
+  context->aci_cause.value.nwsm_cause = cause;
+  /*lint +e613 (Possible use of null pointer 'context' in left argument to operator '->') */
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_get_aci_cause
++------------------------------------------------------------------------------
+| Description : Gets the cause value for a context. Used during retransmissions
+|               etc.
+|
+| Parameters  : context             - context data
++------------------------------------------------------------------------------
+*/
+/*@observer@*/
+T_CAUSE_ps_cause *sm_get_aci_cause(struct T_SM_CONTEXT_DATA *context)
+{
+  TRACE_ASSERT(context != NULL);
+  /*lint -e613 (Possible use of null pointer 'context' in left argument to operator '->') */
+  return &context->aci_cause;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_set_nw_cause
++------------------------------------------------------------------------------
+| Description : Sets the cause value for a context. Used during retransmissions
+|               etc.
+|
+| Parameters  : context             - context data
+|               ctrl_cause          - cause originator
+|               cause               - vause value
++------------------------------------------------------------------------------
+*/
+void sm_set_nw_cause(struct T_SM_CONTEXT_DATA *context,
+		  T_CAUSE_ctrl_value ctrl_cause, U16 cause)
+{
+  TRACE_ASSERT(context != NULL);
+  /*lint -e613 (Possible use of null pointer 'context' in left argument to operator '->') */
+  context->nw_cause.ctrl_value       = ctrl_cause;
+  context->nw_cause.value.nwsm_cause = cause;
+  /*lint +e613 (Possible use of null pointer 'context' in left argument to operator '->') */
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_get_nw_cause
++------------------------------------------------------------------------------
+| Description : Gets the cause value for a context. Used during retransmissions
+|               etc.
+|
+| Parameters  : context             - context data
++------------------------------------------------------------------------------
+*/
+/*@observer@*/
+T_CAUSE_ps_cause *sm_get_nw_cause(struct T_SM_CONTEXT_DATA *context)
+{ 
+TRACE_ASSERT(context != NULL);
+/*lint -e613 (Possible use of null pointer 'context' in left argument to operator '->') */
+#ifdef DEBUG
+  if (context->nw_cause.ctrl_value != CAUSE_is_from_nwsm &&
+      context->nw_cause.ctrl_value != CAUSE_is_from_sm) {
+    (void)TRACE_EVENT_P2("sm_get_nw_cause(): ERROR! Cause element not "
+			 "initialized or not from SM (ctrl=%d, cause=%d)",
+		   context->nw_cause.ctrl_value, context->nw_cause.value.nwsm_cause);
+  }
+#endif
+  return &context->nw_cause;
+/*lint +e613 (Possible use of null pointer 'context' in left argument to operator '->') */
+}
+
+/*==== END OF FILE ==========================================================*/