FreeCalypso > hg > fc-selenite
diff src/g23m-gprs/sm/sm_user_plane_control.c @ 1:d393cd9bb723
src/g23m-*: initial import from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 15 Jul 2018 04:40:46 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-gprs/sm/sm_user_plane_control.c Sun Jul 15 04:40:46 2018 +0000 @@ -0,0 +1,457 @@ +/*---------------------------------------------------------------------------- +| 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: User Plane Control state machine implementation in the SM entity. +| For design details, see: +| 8010.908 SM Detailed Specification ++---------------------------------------------------------------------------*/ + +/*==== DECLARATION CONTROL =================================================*/ + +/*==== INCLUDES =============================================================*/ + +#include "sm.h" + +#include "sm_user_plane_control.h" +#include "sm_context_control.h" + +#include "sm_upm_output_handler.h" + +/*==== CONSTS ===============================================================*/ + +/*==== TYPES ================================================================*/ + +typedef void (*T_SM_USER_PLANE_CONTROL_TRANSITION_FUNC)(struct T_SM_CONTEXT_DATA *ptr_context_data, /*@null@*/ void *data); + +typedef struct { +#ifdef DEBUG + T_SM_USER_PLANE_CONTROL_EVENT event; +#endif /* DEBUG */ + T_SM_USER_PLANE_CONTROL_TRANSITION_FUNC func; +} T_SM_USER_PLANE_CONTROL_TRANSITION; + +/*==== LOCALS ===============================================================*/ + +static void state_event_error(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); +static void ignored (struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); +static void handle_activate_start(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); +static void handle_activate_complete(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); +static void handle_deactivate(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); +static void handle_deactivate_local(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); +static void handle_modify(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); +static void handle_sm_activate_res(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); +static void handle_sm_deactivate_res(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); +static void handle_sm_modify_res(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); + +/*********************************************************************** + * State/Transition Table + */ +static const T_SM_USER_PLANE_CONTROL_TRANSITION +transition[SM_USER_PLANE_CONTROL_NUMBER_OF_STATES][SM_USER_PLANE_CONTROL_NUMBER_OF_EVENTS] = +{ + { /* S0: SM USER PLANE DEACTIVATED */ + M_TRANSITION(SM_P_SM_ACTIVATE_RES, state_event_error), + M_TRANSITION(SM_P_SM_DEACTIVATE_RES, ignored), + M_TRANSITION(SM_P_SM_MODIFY_RES, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_START, handle_activate_start), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_COMPLETE, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE_LOCAL, ignored), + M_TRANSITION(SM_I_USER_PLANE_MODIFY, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE, ignored) + }, + { /* S1: SM USER PLANE ACTIVATE STARTED */ + M_TRANSITION(SM_P_SM_ACTIVATE_RES, state_event_error), + M_TRANSITION(SM_P_SM_DEACTIVATE_RES, state_event_error), + M_TRANSITION(SM_P_SM_MODIFY_RES, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_START, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_COMPLETE, handle_activate_complete), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE_LOCAL, handle_deactivate_local), + M_TRANSITION(SM_I_USER_PLANE_MODIFY, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE, handle_deactivate) + }, + { /* S2: SM USER PLANE ACTIVATE COMPLETING */ + M_TRANSITION(SM_P_SM_ACTIVATE_RES, handle_sm_activate_res), + M_TRANSITION(SM_P_SM_DEACTIVATE_RES, state_event_error), + M_TRANSITION(SM_P_SM_MODIFY_RES, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_START, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_COMPLETE, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE_LOCAL, handle_deactivate_local), + M_TRANSITION(SM_I_USER_PLANE_MODIFY, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE, handle_deactivate) + }, + { /* S3: SM USER PLANE ACTIVATED */ + M_TRANSITION(SM_P_SM_ACTIVATE_RES, state_event_error), + M_TRANSITION(SM_P_SM_DEACTIVATE_RES, state_event_error), + M_TRANSITION(SM_P_SM_MODIFY_RES, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_START, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_COMPLETE, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE_LOCAL, handle_deactivate_local), + M_TRANSITION(SM_I_USER_PLANE_MODIFY, handle_modify), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE, handle_deactivate) + }, + { /* S4: SM USER PLANE MODIFYING */ + M_TRANSITION(SM_P_SM_ACTIVATE_RES, state_event_error), + M_TRANSITION(SM_P_SM_DEACTIVATE_RES, state_event_error), + M_TRANSITION(SM_P_SM_MODIFY_RES, handle_sm_modify_res), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_START, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_COMPLETE, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE_LOCAL, handle_deactivate_local), + M_TRANSITION(SM_I_USER_PLANE_MODIFY, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE, handle_deactivate) + }, + { /* S5: SM USER PLANE DEACTIVATING */ + M_TRANSITION(SM_P_SM_ACTIVATE_RES, state_event_error), + M_TRANSITION(SM_P_SM_DEACTIVATE_RES, handle_sm_deactivate_res), + M_TRANSITION(SM_P_SM_MODIFY_RES, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_START, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_ACTIVATE_COMPLETE, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE_LOCAL, handle_deactivate_local), + M_TRANSITION(SM_I_USER_PLANE_MODIFY, state_event_error), + M_TRANSITION(SM_I_USER_PLANE_DEACTIVATE, ignored) + } +}; + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +/* ++------------------------------------------------------------------------------ +| Function : state_event_error ++------------------------------------------------------------------------------ +| Description : General function used to report state event errors. +| +| Parameters : context - Not used +| data - Not used ++------------------------------------------------------------------------------ +*/ +static void state_event_error(/*@unused@*/ struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data) +{ + (void)TRACE_ERROR("SM User Plane Control: STATE EVENT ERROR!"); +} + +/* ++------------------------------------------------------------------------------ +| Function : ignored ++------------------------------------------------------------------------------ +| Description : General function used for transitions that shall be ignored +| +| Parameters : context - Not used +| data - Not used ++------------------------------------------------------------------------------ +*/ +static void ignored(/*@unused@*/ struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data) +{ + (void)TRACE_FUNCTION("SM User Plane Control: Event ignored."); +} + +/* ++------------------------------------------------------------------------------ +| Function : handle_activate_start ++------------------------------------------------------------------------------ +| Description : Handle event SM_I_USER_PLANE_ACTIVATE_START in S0 +| +| Parameters : context - Context data +| data - Not used ++------------------------------------------------------------------------------ +*/ +static void handle_activate_start(struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data) +{ + (void)TRACE_FUNCTION("handle_activate_start"); + + /* Send SM_ACTIVATE_STARTED_IND */ + send_sm_activate_started_ind(context); + + /* Go to state SM USER PLANE ACTIVATE STARTED */ + context->user_plane_control_state = SM_USER_PLANE_ACTIVATE_STARTED; +} + +/* ++------------------------------------------------------------------------------ +| Function : handle_activate_complete ++------------------------------------------------------------------------------ +| Description : Handle event SM_I_USER_PLANE_ACTIVATE_COMPLETE in S1 +| +| Parameters : context - Context data +| data - Not used ++------------------------------------------------------------------------------ +*/ +static void handle_activate_complete(struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data) +{ + (void)TRACE_FUNCTION("handle_activate_complete"); + + /* Send SM_ACTIVATE_IND */ + send_sm_activate_ind(context); + + /* Go to state SM USER PLANE ACTIVATE COMPLETING */ + context->user_plane_control_state = SM_USER_PLANE_ACTIVATE_COMPLETING; +} + +/* ++------------------------------------------------------------------------------ +| Function : handle_modify ++------------------------------------------------------------------------------ +| Description : Handle event SM_I_USER_PLANE_MODIFY in S3 +| +| Parameters : context - Context data +| data - Update flags ++------------------------------------------------------------------------------ +*/ +static void handle_modify(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) +{ + (void)TRACE_FUNCTION("handle_modify"); + + /* Send SM_MODIFY_IND */ + send_sm_modify_ind(context); + + /* Go to state SM USER PLANE MODIFYING */ + context->user_plane_control_state = SM_USER_PLANE_MODIFYING; +} + +/* ++------------------------------------------------------------------------------ +| Function : handle_deactivate ++------------------------------------------------------------------------------ +| Description : Handle event SM_I_USER_PLANE_DEACTIVATE in any state +| +| Parameters : context - Context data +| data - PS_rel_ind ++------------------------------------------------------------------------------ +*/ +static void handle_deactivate(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) +{ + (void)TRACE_FUNCTION("handle_deactivate"); + + /* Send SM_DEACTIVATE_IND with local parameter taken from input */ + send_sm_deactivate_ind(sm_nsapi2nsapi_set(context->nsapi), + (data == NULL ? PS_REL_IND_NO : PS_REL_IND_YES)); + + /* Go to state SM USER PLANE DEACTIVATING */ + context->user_plane_control_state = SM_USER_PLANE_DEACTIVATING; +} + +/* ++------------------------------------------------------------------------------ +| Function : handle_deactivate_local ++------------------------------------------------------------------------------ +| Description : Handle event SM_I_USER_PLANE_DEACTIVATE_LOCAL in any state +| +| Parameters : context - Context data +| data - BOOL (TRUE = send SM_DEACTIVATE_IND) ++------------------------------------------------------------------------------ +*/ +static void handle_deactivate_local(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) +{ + (void)TRACE_FUNCTION("handle_deactivate_local"); + + if (data) + { + /* Send SM_DEACTIVATE_IND with local parameter true */ + send_sm_deactivate_ind(sm_nsapi2nsapi_set(context->nsapi), PS_REL_IND_YES); + + /* Go to state SM USER PLANE DEACTIVATING */ + context->user_plane_control_state = SM_USER_PLANE_DEACTIVATING; + } else { + /* Go to state SM USER PLANE DEACTIVATED */ + context->user_plane_control_state = SM_USER_PLANE_DEACTIVATED; + } +} + +/* ++------------------------------------------------------------------------------ +| Function : handle_sm_activate_res ++------------------------------------------------------------------------------ +| Description : Handle event SM_P_SM_ACTIVATE_RES in S2 +| +| Parameters : context - Context data +| data - Not used ++------------------------------------------------------------------------------ +*/ +static void handle_sm_activate_res(struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data) +{ + (void)TRACE_FUNCTION("handle_sm_activate_res"); + + /* Go to state SM USER PLANE ACTIVATED */ + context->user_plane_control_state = SM_USER_PLANE_ACTIVATED; + + /* If comp params is sent by UPM copy it to context. When SMREG_ACTIVATE_CNF + * primitive is composed this values are copied. + */ + if ( (((T_SM_ACTIVATE_RES*)data)->v_comp_params == TRUE) ) + { + memcpy(&context->comp_params, &((T_SM_ACTIVATE_RES*)data)->comp_params, + sizeof(T_NAS_comp_params)); + } else { + memset(&context->comp_params, 0, sizeof(T_NAS_comp_params)); + } + /* Notify Context Control of activation completion */ + sm_context_control(context, SM_I_USER_PLANE_ACTIVATED, NULL); +} + +/* ++------------------------------------------------------------------------------ +| Function : handle_sm_deactivate_res ++------------------------------------------------------------------------------ +| Description : Handle event SM_P_SM_DEACTIVATE_RES in S5 +| +| Parameters : context - Context data +| data - Not used ++------------------------------------------------------------------------------ +*/ +static void handle_sm_deactivate_res(struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data) +{ + (void)TRACE_FUNCTION("handle_sm_deactivate_res"); + + /* Go to state SM USER PLANE DEACTIVATED */ + context->user_plane_control_state = SM_USER_PLANE_DEACTIVATED; + + /* Notify Context Control of deactivation completion */ + sm_context_control(context, SM_I_USER_PLANE_DEACTIVATED, NULL); +} + +/* ++------------------------------------------------------------------------------ +| Function : handle_sm_modify_res ++------------------------------------------------------------------------------ +| Description : Handle event SM_P_SM_MODIFY_RES in S4 +| +| Parameters : context - Context data +| data - Not used ++------------------------------------------------------------------------------ +*/ +static void handle_sm_modify_res(struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data) +{ + (void)TRACE_FUNCTION("handle_sm_modify_res"); + + /* Go to state SM USER PLANE ACTIVATED */ + context->user_plane_control_state = SM_USER_PLANE_ACTIVATED; + + /* Notify Context Control of modification completion */ + sm_context_control(context, SM_I_USER_PLANE_MODIFIED, NULL); +} + +/*==== PUBLIC FUNCTIONS =====================================================*/ + +/* ++------------------------------------------------------------------------------ +| Function : sm_user_plane_control_init ++------------------------------------------------------------------------------ +| Description : User Plane Control state machine initialization function + +| Parameters : context - Context data ++------------------------------------------------------------------------------ +*/ +void sm_user_plane_control_init(struct T_SM_CONTEXT_DATA *context) +{ + (void)TRACE_FUNCTION("sm_user_plane_control_init"); + + context->user_plane_control_state = SM_USER_PLANE_DEACTIVATED; +} + +/* ++------------------------------------------------------------------------------ +| Function : sm_user_plane_control_exit ++------------------------------------------------------------------------------ +| Description : User Plane Control state machine exit function + +| Parameters : context - Context data ++------------------------------------------------------------------------------ +*/ +void sm_user_plane_control_exit(struct T_SM_CONTEXT_DATA *context) +{ + (void)TRACE_FUNCTION("sm_user_plane_control_exit"); + + context->user_plane_control_state = SM_USER_PLANE_DEACTIVATED; +} + +/* ++------------------------------------------------------------------------------ +| Function : sm_user_plane_control_state ++------------------------------------------------------------------------------ +| Description : Returns a read-only string with the name of the active state. + +| Parameters : context - Context data ++------------------------------------------------------------------------------ +*/ +#ifdef DEBUG +/*@observer@*/const char * +sm_user_plane_control_state(struct T_SM_CONTEXT_DATA *context) +{ + /*@observer@*/ + static const char *state_name[SM_USER_PLANE_CONTROL_NUMBER_OF_STATES] = { + "S0_SM_USER_PLANE_DEACTIVATED", + "S1_SM_USER_PLANE_ACTIVATE_STARTED", + "S2_SM_USER_PLANE_ACTIVATE_COMPLETING", + "S3_SM_USER_PLANE_ACTIVATED", + "S4_SM_USER_PLANE_MODIFYING", + "S5_SM_USER_PLANE_DEACTIVATING" + }; + + TRACE_ASSERT(context->user_plane_control_state < SM_USER_PLANE_CONTROL_NUMBER_OF_STATES); + + return state_name[(U16)context->user_plane_control_state]; +} +#endif + +/* ++------------------------------------------------------------------------------ +| Function : sm_user_plane_control ++------------------------------------------------------------------------------ +| Description : User Plane Control state machine +| +| Parameters : context - Context data +| event - Internal event (see sm_user_plane_control.h) +| data - Event dependent parameter ++------------------------------------------------------------------------------ +*/ +void sm_user_plane_control(struct T_SM_CONTEXT_DATA *context, + T_SM_USER_PLANE_CONTROL_EVENT event, + /*@null@*/ void *data) +{ +#ifdef DEBUG + const char *old_state_name, *new_state_name; + T_SM_USER_PLANE_CONTROL_STATE old_state; + /*@observer@*/ + static const char *event_name[SM_USER_PLANE_CONTROL_NUMBER_OF_EVENTS] = { + "SM_P_SM_ACTIVATE_RES", + "SM_P_SM_DEACTIVATE_RES", + "SM_P_SM_MODIFY_RES", + "SM_I_USER_PLANE_ACTIVATE_START", + "SM_I_USER_PLANE_ACTIVATE_COMPLETE", + "SM_I_USER_PLANE_DEACTIVATE_LOCAL", + "SM_I_USER_PLANE_MODIFY", + "SM_I_USER_PLANE_DEACTIVATE" + }; + + TRACE_ASSERT(event < SM_USER_PLANE_CONTROL_NUMBER_OF_EVENTS); + + old_state = context->user_plane_control_state; + old_state_name = sm_user_plane_control_state(context); + + if (transition[(U16)old_state][(U16)event].event != event) { + (void)TRACE_ERROR("Event table error in sm_user_plane_control!"); + } +#endif /* DEBUG */ + + transition[(U16)context->user_plane_control_state] + [(U16)event].func(context, data); + +#ifdef DEBUG + new_state_name = sm_user_plane_control_state(context); + + (void)TRACE_EVENT_P4("SM U-PLANE #%d: %s => %s to %s", context->nsapi, + event_name[(U16)event], old_state_name, new_state_name); +#endif /* DEBUG */ +} + +/*==== END OF FILE ==========================================================*/