FreeCalypso > hg > fc-tourmaline
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 ==========================================================*/