FreeCalypso > hg > fc-magnetite
view src/g23m-gprs/sm/sm_network_control.c @ 481:24078551b620
build system: set ALLOW_CSIM_GSM=1 by default for hybrid configs
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 19 Jun 2018 06:39:18 +0000 |
parents | 219afcfc6250 |
children |
line wrap: on
line source
/*---------------------------------------------------------------------------- | 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: Network 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_network_control.h" #include "sm_context_control.h" #include "sm_mm_output_handler.h" #include "sm_qos.h" #include "sm_tft.h" #include "sm_timer_handler.h" /*==== CONSTS ===============================================================*/ /*==== TYPES ================================================================*/ typedef void (*T_SM_NETWORK_CONTROL_TRANSITION_FUNC)(struct T_SM_CONTEXT_DATA *ptr_context_data, /*@null@*/ void *data); typedef struct { #ifdef DEBUG T_SM_NETWORK_CONTROL_EVENT event; #endif /* DEBUG */ T_SM_NETWORK_CONTROL_TRANSITION_FUNC func; } T_SM_NETWORK_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 message_incompatible_with_state(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void message_for_invalid_ti(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); /* Handler functions for internal events */ static void handle_activate_primary(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_activate_secondary(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_request_activation_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_modify_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_deactivate_in_S0(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_deactivate_during_activation(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_deactivate_during_modification(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_deactivate_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_deactivate_local(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); /* Handler functions for incoming air interface messages */ static void handle_activate_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_activate_pdp_context_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_activate_secondary_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_activate_secondary_pdp_context_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_request_pdp_context_activation_in_S0(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_request_pdp_context_activation_in_S1(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_request_pdp_context_activation_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_modify_pdp_context_request_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_modify_pdp_context_request_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_modify_pdp_context_request_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_modify_pdp_context_request_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_modify_pdp_context_accept_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_modify_pdp_context_accept_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_modify_pdp_context_accept_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_modify_pdp_context_reject_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_modify_pdp_context_reject_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_modify_pdp_context_reject_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_deactivate_pdp_context_request_while_active(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_deactivate_pdp_context_request_while_deactivating(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_deactivate_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); /* Handler functions for timer timeouts */ static void handle_T3380(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_T3380_max (struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_T3381 (struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_T3381_max_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_T3381_max_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_T3381_max_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_T3390 (struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_T3390_max (struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); /* Handler functions for incoming primitives */ static void handle_mmpm_suspend_ind(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); static void handle_mmpm_resume_ind(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data); /*********************************************************************** * State/Transition Table */ static const T_SM_NETWORK_CONTROL_TRANSITION transition[SM_NETWORK_CONTROL_NUMBER_OF_STATES][SM_NETWORK_CONTROL_NUMBER_OF_EVENTS] = { { /* S0: SM NETWORK DEACTIVATED */ M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_for_invalid_ti), M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_for_invalid_ti), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_for_invalid_ti), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_for_invalid_ti), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, state_event_error), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, state_event_error), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, message_for_invalid_ti), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, message_for_invalid_ti), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, message_for_invalid_ti), M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, handle_request_pdp_context_activation_in_S0), M_TRANSITION(SM_M_SM_STATUS, state_event_error), M_TRANSITION(SM_P_MMPM_RESUME_IND, ignored), M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind), M_TRANSITION(SM_T_T3380, state_event_error), M_TRANSITION(SM_T_T3380_MAX, state_event_error), M_TRANSITION(SM_T_T3381, state_event_error), M_TRANSITION(SM_T_T3381_MAX, state_event_error), M_TRANSITION(SM_T_T3390, state_event_error), M_TRANSITION(SM_T_T3390_MAX, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, handle_activate_primary), M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, handle_activate_secondary), M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local), M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error), M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, handle_request_activation_reject), M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_in_S0) }, { /* S1: SM NETWORK ACTIVATING PRIMARY */ M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, handle_activate_pdp_context_accept), M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, handle_activate_pdp_context_reject), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, handle_request_pdp_context_activation_in_S1), M_TRANSITION(SM_M_SM_STATUS, state_event_error), M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind), M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind), M_TRANSITION(SM_T_T3380, handle_T3380), M_TRANSITION(SM_T_T3380_MAX, handle_T3380_max), M_TRANSITION(SM_T_T3381, state_event_error), M_TRANSITION(SM_T_T3381_MAX, state_event_error), M_TRANSITION(SM_T_T3390, state_event_error), M_TRANSITION(SM_T_T3390_MAX, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local), M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error), M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_during_activation) }, { /* S2: SM NETWORK ACTIVATING SECONDARY */ M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, handle_activate_secondary_pdp_context_accept), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, handle_activate_secondary_pdp_context_reject), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, message_incompatible_with_state), M_TRANSITION(SM_M_SM_STATUS, state_event_error), M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind), M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind), M_TRANSITION(SM_T_T3380, handle_T3380), M_TRANSITION(SM_T_T3380_MAX, handle_T3380_max), M_TRANSITION(SM_T_T3381, state_event_error), M_TRANSITION(SM_T_T3381_MAX, state_event_error), M_TRANSITION(SM_T_T3390, state_event_error), M_TRANSITION(SM_T_T3390_MAX, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local), M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error), M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_during_activation) }, { /* S3: SM NETWORK ACTIVATING ADDING TFTS */ M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, handle_modify_pdp_context_request_in_S3), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, handle_modify_pdp_context_accept_in_S3), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, handle_modify_pdp_context_reject_in_S3), M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, message_incompatible_with_state), M_TRANSITION(SM_M_SM_STATUS, state_event_error), M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind), M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind), M_TRANSITION(SM_T_T3380, state_event_error), M_TRANSITION(SM_T_T3380_MAX, state_event_error), M_TRANSITION(SM_T_T3381, handle_T3381), M_TRANSITION(SM_T_T3381_MAX, handle_T3381_max_in_S3), M_TRANSITION(SM_T_T3390, state_event_error), M_TRANSITION(SM_T_T3390_MAX, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local), M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error), M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_during_modification) }, { /* S4: SM NETWORK ACTIVATED */ M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, handle_modify_pdp_context_request_in_S4), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, handle_request_pdp_context_activation_in_S4), M_TRANSITION(SM_M_SM_STATUS, state_event_error), M_TRANSITION(SM_P_MMPM_RESUME_IND, ignored), M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind), M_TRANSITION(SM_T_T3380, state_event_error), M_TRANSITION(SM_T_T3380_MAX, state_event_error), M_TRANSITION(SM_T_T3381, state_event_error), M_TRANSITION(SM_T_T3381_MAX, state_event_error), M_TRANSITION(SM_T_T3390, state_event_error), M_TRANSITION(SM_T_T3390_MAX, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local), M_TRANSITION(SM_I_NETWORK_MODIFY, handle_modify_in_S4), M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_in_S4) }, { /* S5: SM NETWORK MODIFYING */ M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, handle_modify_pdp_context_request_in_S5), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, handle_modify_pdp_context_accept_in_S5), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, handle_modify_pdp_context_reject_in_S5), M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, message_incompatible_with_state), M_TRANSITION(SM_M_SM_STATUS, state_event_error), M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind), M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind), M_TRANSITION(SM_T_T3380, state_event_error), M_TRANSITION(SM_T_T3380_MAX, state_event_error), M_TRANSITION(SM_T_T3381, handle_T3381), M_TRANSITION(SM_T_T3381_MAX, handle_T3381_max_in_S5), M_TRANSITION(SM_T_T3390, state_event_error), M_TRANSITION(SM_T_T3390_MAX, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local), M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error), M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_during_modification) }, { /* S6: SM NETWORK MODIFYING ADDITIONAL TFTS */ M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, handle_modify_pdp_context_request_in_S6), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, handle_modify_pdp_context_accept_in_S6), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, handle_modify_pdp_context_reject_in_S6), M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, message_incompatible_with_state), M_TRANSITION(SM_M_SM_STATUS, state_event_error), M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind), M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind), M_TRANSITION(SM_T_T3380, state_event_error), M_TRANSITION(SM_T_T3380_MAX, state_event_error), M_TRANSITION(SM_T_T3381, handle_T3381), M_TRANSITION(SM_T_T3381_MAX, handle_T3381_max_in_S6), M_TRANSITION(SM_T_T3390, state_event_error), M_TRANSITION(SM_T_T3390_MAX, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local), M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error), M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_during_modification) }, { /* S7: SM NETWORK DEACTIVATING */ M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_deactivating), M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, handle_deactivate_pdp_context_accept), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state), M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, message_incompatible_with_state), M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, message_incompatible_with_state), M_TRANSITION(SM_M_SM_STATUS, state_event_error), M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind), M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind), M_TRANSITION(SM_T_T3380, state_event_error), M_TRANSITION(SM_T_T3380_MAX, state_event_error), M_TRANSITION(SM_T_T3381, state_event_error), M_TRANSITION(SM_T_T3381_MAX, state_event_error), M_TRANSITION(SM_T_T3390, handle_T3390), M_TRANSITION(SM_T_T3390_MAX, handle_T3390_max), M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error), M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local), M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error), M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error), M_TRANSITION(SM_I_NETWORK_DEACTIVATE, ignored) } }; /*==== PRIVATE FUNCTIONS ====================================================*/ /* +------------------------------------------------------------------------------ | Function : sm_nw_mark_context_active +------------------------------------------------------------------------------ | Description : Mark context in network state ACTIVE | | Parameters : nsapi - context index +------------------------------------------------------------------------------ */ static void sm_nw_mark_context_active(int /*@alt U8@*/ nsapi) { sm_data.sm_context_activation_status = sm_add_nsapi_to_nsapi_set(nsapi, sm_data.sm_context_activation_status); } /* +------------------------------------------------------------------------------ | Function : sm_nw_mark_context_inactive +------------------------------------------------------------------------------ | Description : Mark context in network state INACTIVE | | Parameters : nsapi - context index +------------------------------------------------------------------------------ */ static void sm_nw_mark_context_inactive(int /*@alt U8@*/ nsapi) { sm_data.sm_context_activation_status = sm_remove_nsapi_from_nsapi_set(nsapi, sm_data.sm_context_activation_status); } /* +------------------------------------------------------------------------------ | Function : sm_nw_mark_nsapi_set_inactive +------------------------------------------------------------------------------ | Description : Mark a set of contexts in network state INACTIVE | | Parameters : nsapi_set - Set of NSAPIs to mark inactive +------------------------------------------------------------------------------ */ static void sm_nw_mark_nsapi_set_inactive(U16 nsapi_set) { sm_data.sm_context_activation_status &= 0xffff ^ nsapi_set; } /* +------------------------------------------------------------------------------ | Function : sm_nw_get_next_free_ti +------------------------------------------------------------------------------ | Description : Traverse sm_context_array and find the lowest unused TI. | | Parameters : context - context that needs TI +------------------------------------------------------------------------------ */ static U8 sm_nw_get_next_free_ti(struct T_SM_CONTEXT_DATA *context_to_get_ti) { int nsapi; U16 ti_mask = (U16)0x07ff; /* Iterate through sm_context_array and find the lowest available TI */ for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) { struct T_SM_CONTEXT_DATA *context; context = sm_get_context_data_from_nsapi(nsapi); if (context != NULL && context != context_to_get_ti && (context->ti & (U8)SM_TI_FLAG) == (U8)0 ) { ti_mask &= 0x7ff ^ (1 << context->ti); } } if (ti_mask != 0) { int index; for (index = 0; index < SM_MAX_NSAPI_OFFSET && (ti_mask & (1UL << (U16)index)) == 0; index++) {}; return (U8)index; } else { /* No TIs available */ return (U8)0; } } /* +------------------------------------------------------------------------------ | Function : sm_nw_initiate_deactivation +------------------------------------------------------------------------------ | Description : General function for aborting a procedure and deactivating | | Parameters : context - context data +------------------------------------------------------------------------------ */ static void sm_nw_initiate_deactivation(struct T_SM_CONTEXT_DATA *context, T_CAUSE_ps_cause *ps_cause) { /* Stop any active timer and start T3390 in stead */ sm_timer_stop(context); sm_timer_start(context, SM_TIMER_T3390); /* Send message DEACTIVATE PDP CONTEXT REQUEST */ send_msg_deactivate_pdp_context_request(context, ps_cause, FALSE); } /* +------------------------------------------------------------------------------ | Function : sm_nw_store_mt_modify_parameters +------------------------------------------------------------------------------ | Description : Examines a T_D_MODIFY_PDP_CONTEXT_REQUEST message and stores | the parameters included. Returns flags which indicate the | parameters that were updated. | | Parameters : context - context data | msg - T_D_MODIFY_PDP_CONTEXT_REQUEST +------------------------------------------------------------------------------ */ static T_SM_UPDATE_FLAGS sm_nw_store_mt_modify_parameters(struct T_SM_CONTEXT_DATA *context, T_D_MODIFY_PDP_CONTEXT_REQUEST *msg) { T_SM_UPDATE_FLAGS update_flags; sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos); update_flags = SM_UPDATE_QOS; /* Store GSM RAT parameters, if present */ if (context->radio_prio != msg->radio_prio.radio_prio_val || context->sapi != msg->llc_sapi.sapi) { context->radio_prio = msg->radio_prio.radio_prio_val; context->sapi = msg->llc_sapi.sapi; update_flags |= SM_UPDATE_SAPI_RADIO_PRIO_PFI; } /* Store PFI, if present */ if (msg->v_pfi != (U8)FALSE && msg->pfi.pfi_val != context->pfi) { sm_set_pfi_included(context, TRUE); context->pfi = msg->pfi.pfi_val; update_flags |= SM_UPDATE_SAPI_RADIO_PRIO_PFI; } /* IP address "modified" (== assigned late)? Store, if so. */ if (msg->v_address != (U8)FALSE) { sm_nw_store_negotiated_address(context, &msg->address, msg->v_address); update_flags |= SM_UPDATE_ADDRESS; } return update_flags; } /* +------------------------------------------------------------------------------ | Function : sm_nw_store_modify_accept_parameters +------------------------------------------------------------------------------ | Description : Examines a T_D_MODIFY_PDP_CONTEXT_ACCEPT message and stores | the parameters included. Returns flags which indicate the | parameters that were updated. | | Parameters : context - context data | msg - T_D_MODIFY_PDP_CONTEXT_REQUEST +------------------------------------------------------------------------------ */ static T_SM_UPDATE_FLAGS sm_nw_store_modify_accept_parameters(struct T_SM_CONTEXT_DATA *context, T_D_MODIFY_PDP_CONTEXT_ACCEPT *msg) { T_SM_UPDATE_FLAGS update_flags = (T_SM_UPDATE_FLAGS)0; /* Store GSM RAT parameters, if present */ if (msg->v_llc_sapi != (U8)FALSE) { context->sapi = msg->llc_sapi.sapi; update_flags = SM_UPDATE_SAPI_RADIO_PRIO_PFI; } if (msg->v_radio_prio != (U8)FALSE && msg->radio_prio.radio_prio_val != context->radio_prio) { context->radio_prio = msg->radio_prio.radio_prio_val; update_flags = SM_UPDATE_SAPI_RADIO_PRIO_PFI; } /* Store PFI, if present */ if (msg->v_pfi != (U8)FALSE && msg->pfi.pfi_val != context->pfi) { sm_set_pfi_included(context, TRUE); context->pfi = msg->pfi.pfi_val; update_flags = SM_UPDATE_SAPI_RADIO_PRIO_PFI; } return update_flags; } /* +------------------------------------------------------------------------------ | 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 Network 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 Network Control: Event ignored."); } /* +------------------------------------------------------------------------------ | Function : message_incompatible_with_state +------------------------------------------------------------------------------ | Description : General function used for reporting illegal air interface | messages in the current state | | Parameters : context - Context data | data - Not used +------------------------------------------------------------------------------ */ static void message_incompatible_with_state(/*@unused@*/ struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data) { (void)TRACE_FUNCTION("message_incompatible_with_state"); sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_MSG_TYPE_INCOMPATIBLE_WITH_STATE); send_msg_sm_status(context->ti, sm_get_nw_cause(context)); } /* +------------------------------------------------------------------------------ | Function : message_for_invalid_ti +------------------------------------------------------------------------------ | Description : General function used for replying to network messages | received for a context in state S0 (invalid TI) | | Parameters : context - Context data | data - Not used +------------------------------------------------------------------------------ */ static void message_for_invalid_ti(/*@unused@*/ struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data) { (void)TRACE_FUNCTION("message_for_invalid_ti"); sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_INVALID_TI); send_msg_sm_status(context->ti, sm_get_nw_cause(context)); } /* +------------------------------------------------------------------------------ | Function : handle_activate_primary +------------------------------------------------------------------------------ | Description : Handle event SM_I_NETWORK_ACTIVATE_PRIMARY in S0 | | Parameters : context - Context data | data - SMREG_PDP_ACTIVATE_REQ * +------------------------------------------------------------------------------ */ static void handle_activate_primary(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_SMREG_PDP_ACTIVATE_REQ *prim = (T_SMREG_PDP_ACTIVATE_REQ *)data; (void)TRACE_FUNCTION("handle_activate_primary"); if (prim != NULL) { memcpy(&context->comp_params, &prim->comp_params, sizeof(T_NAS_comp_params)); sm_qos_copy_to_sm(&context->requested_qos, &prim->qos, prim->ctrl_qos); sm_qos_copy_to_sm(&context->minimum_qos, (T_PS_qos *)&prim->min_qos, (T_PS_ctrl_qos)prim->ctrl_min_qos); sm_nw_store_requested_address(context, prim->pdp_type, prim->ctrl_ip_address, &prim->ip_address); /* Free APN (necessary if this is a network requested activation) */ sm_nw_free_apn(context); /* Store APN for negotiation, if present */ if (prim->apn.c_apn_buf > (U8)0) { sm_nw_allocate_and_copy_apn(context, prim->apn.c_apn_buf, prim->apn.apn_buf); } /* Store TFT for later addition, if present */ TRACE_ASSERT(context->requested_tft.ptr_tft_pf == NULL); if (prim->v_tft != (U8)FALSE && prim->tft.c_tft_pf > (U8)0) { sm_nw_allocate_and_copy_requested_tft(context, &prim->tft); } else { context->requested_tft.c_tft_pf = (U8)0; } /* Store PCO for negotiation, if present */ sm_nw_free_requested_pco(context); if (prim->sdu.l_buf > 0) { U16 pco_len = prim->sdu.l_buf >> 3; sm_nw_allocate_and_copy_requested_pco(context, pco_len, &prim->sdu.buf[(prim->sdu.o_buf >> 3)]); } /* Allocate TI for context unless this was a NW initiated activation */ if ((context->ti & SM_TI_FLAG) == (U8)0) { context->ti = sm_nw_get_next_free_ti(context); } } else { /* No SMREG primitive: This is a re-activation. Use current parameters. */ /* The following function call can cause problems in reactivation cases * where the first pdp context uses dynamic addressing. When the following * function is called the 'reactivated' context uses address issued by the * network for the first pdp activation. This will result in static addressing * and may cause pdp activation reject from networks that doesn't support * static addressing. */ /*sm_nw_copy_negotiated_address_to_requested(context);*/ } /* Mark context as active */ sm_nw_mark_context_active(context->nsapi); /* Start timer T3380 for this NSAPI/context */ sm_timer_start(context, SM_TIMER_T3380); /* Send ACTIVATE PDP CONTEXT REQUEST message */ send_msg_activate_pdp_context_request(context); /* Go to state SM NETWORK ACTIVATING PRIMARY */ context->network_control_state = SM_NETWORK_ACTIVATING_PRIMARY; } /* +------------------------------------------------------------------------------ | Function : handle_activate_secondary +------------------------------------------------------------------------------ | Description : Handle event SM_I_NETWORK_ACTIVATE_SECONDARY in S0 | | Parameters : context - Context data | data - T_SMREG_PDP_ACTIVATE_SEC_REQ * +------------------------------------------------------------------------------ */ static void handle_activate_secondary(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_SMREG_PDP_ACTIVATE_SEC_REQ *prim = (T_SMREG_PDP_ACTIVATE_SEC_REQ *)data; (void)TRACE_FUNCTION("handle_activate_secondary"); if (prim != NULL) { memcpy(&context->comp_params, &prim->comp_params, sizeof(T_NAS_comp_params)); sm_qos_copy_to_sm(&context->requested_qos, &prim->qos, prim->ctrl_qos); sm_qos_copy_to_sm(&context->minimum_qos, (T_PS_qos *)&prim->min_qos, (T_PS_ctrl_qos)prim->ctrl_min_qos); /* Store TFT for later addition, if present */ sm_nw_free_requested_tft(context); if (prim->v_tft != (U8)FALSE && prim->tft.c_tft_pf > (U8)0) { sm_nw_allocate_and_copy_requested_tft(context, &prim->tft); } else { context->requested_tft.c_tft_pf = (U8)0; } /* Allocate TI for context */ context->ti = sm_nw_get_next_free_ti(context); } else { /* No SMREG primitive: This is a re-activation. Use current parameters. */ } /* Mark context as active */ sm_nw_mark_context_active(context->nsapi); /* Start timer T3380 for this NSAPI/context */ sm_timer_start(context, SM_TIMER_T3380); /* Send ACTIVATE SECONDARY PDP CONTEXT REQUEST message */ send_msg_activate_secondary_pdp_context_request(context); /* Go to state SM NETWORK ACTIVATING SECONDARY */ context->network_control_state = SM_NETWORK_ACTIVATING_SECONDARY; } /* +------------------------------------------------------------------------------ | Function : handle_request_activation_reject +------------------------------------------------------------------------------ | Description : Handle event SM_I_NETWORK_REQUEST_ACTIVATION_REJECT in S0 | | Parameters : context - Context data | data - Not used (cause set in context data) +------------------------------------------------------------------------------ */ static void handle_request_activation_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/ void *data) { (void)TRACE_FUNCTION("handle_request_activation_reject"); /* Send REQUEST PDP CONTEXT ACTIVATION REJECT message */ send_msg_request_pdp_context_activation_reject(context, sm_get_nw_cause(context)); } /* +------------------------------------------------------------------------------ | Function : handle_modify_in_S4 +------------------------------------------------------------------------------ | Description : Handle event SM_I_NETWORK_MODIFY in S4 | | Parameters : context - Context data | data - T_SMREG_PDP_MODIFY_REQ * +------------------------------------------------------------------------------ */ static void handle_modify_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_SMREG_PDP_MODIFY_REQ *prim = (T_SMREG_PDP_MODIFY_REQ *)data; BOOL start_modification = FALSE; (void)TRACE_FUNCTION("handle_modify_in_S4"); /* If prim == NULL this is a context upgrade (RAB re-establishment) */ if (prim != NULL) { if (prim->ctrl_qos != PS_is_qos_not_present) { sm_qos_copy_to_sm(&context->requested_qos, &prim->qos, prim->ctrl_qos); start_modification = TRUE; } if (prim->ctrl_min_qos != PS_is_min_qos_not_present) { sm_qos_copy_to_sm(&context->minimum_qos, (T_PS_qos *)&prim->min_qos, (T_PS_ctrl_qos)prim->ctrl_min_qos); if (!sm_qos_is_minimum_satisfied_by_sm(context, &context->accepted_qos)) { start_modification = TRUE; } } /* Store TFT for later addition, if present */ if (prim->v_tft != (U8)FALSE) { if (prim->tft.c_tft_pf > (U8)0) { sm_nw_allocate_and_copy_requested_tft(context, &prim->tft); } else { context->requested_tft.c_tft_pf = (U8)0; } if (sm_tft_more_to_modify(context)) { start_modification = TRUE; } } } else { /* Prim == NULL: context upgrade (RAB re-establishment) */ /* Start modification with originally requested parameters */ start_modification = TRUE; } if (start_modification) { /* Start timer T3381 for this NSAPI/context */ sm_timer_start(context, SM_TIMER_T3381); /* Send MODIFY PDP CONTEXT REQUEST message */ send_msg_modify_pdp_context_request(context); /* Go to state SM NETWORK MODIFYING */ context->network_control_state = SM_NETWORK_MODIFYING; } } /* +------------------------------------------------------------------------------ | Function : handle_deactivate_in_S0 +------------------------------------------------------------------------------ | Description : Handle event SM_I_NETWORK_DEACTIVATE in S0 | | Parameters : context - Context data | data - rel_ind flag +------------------------------------------------------------------------------ */ static void handle_deactivate_in_S0(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { (void)TRACE_FUNCTION("handle_deactivate_in_S0"); /* Report success deactivation to Context Control (already inactive) */ sm_context_control(context, SM_I_NETWORK_DEACTIVATE_COMPLETED, data); } /* +------------------------------------------------------------------------------ | Function : handle_deactivate_during_activation +------------------------------------------------------------------------------ | Description : Handle event SM_I_NETWORK_DEACTIVATE in S1 or S2 | | Parameters : context - Context data | data - Cause (T_CAUSE_ps_cause *) +------------------------------------------------------------------------------ */ static void handle_deactivate_during_activation(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { (void)TRACE_FUNCTION("handle_deactivate_during_activation"); TRACE_ASSERT(data != NULL); /* Go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Stop T3380, and start deactivation */ sm_nw_initiate_deactivation(context, (T_CAUSE_ps_cause *)data); } /* +------------------------------------------------------------------------------ | Function : handle_deactivate_in_S4 +------------------------------------------------------------------------------ | Description : Handle event SM_I_NETWORK_DEACTIVATE in S4 | | Parameters : context - Context data | data - Cause (T_CAUSE_ps_cause *) +------------------------------------------------------------------------------ */ static void handle_deactivate_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { (void)TRACE_FUNCTION("handle_deactivate_in_S4"); TRACE_ASSERT(data != NULL); /* Go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Initiate deactivation; data contains cause */ sm_nw_initiate_deactivation(context, (T_CAUSE_ps_cause *)data); } /* +------------------------------------------------------------------------------ | Function : handle_deactivate_during_modification +------------------------------------------------------------------------------ | Description : Handle event SM_I_NETWORK_DEACTIVATE in S3, S5, or S6 | | Parameters : context - Context data | data - Cause (T_CAUSE_ps_cause *) +------------------------------------------------------------------------------ */ static void handle_deactivate_during_modification(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { (void)TRACE_FUNCTION("handle_deactivate_during_modification"); TRACE_ASSERT(data != NULL); /* Go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Initiate deactivation; data contains cause */ sm_nw_initiate_deactivation(context, (T_CAUSE_ps_cause *)data); } /* +------------------------------------------------------------------------------ | Function : handle_deactivate_local +------------------------------------------------------------------------------ | Description : Handle SM_I_NETWORK_DEACTIVATE_LOCAL | | Parameters : context - context data | data - unused +------------------------------------------------------------------------------ */ static void handle_deactivate_local(struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data) { /* Remove active TFT - this is necessary in case of reactivations */ sm_nw_free_active_tft(context); /* Free stored coded message - if any */ sm_free_coded_msg(context); /* Mark context as inactive */ sm_nw_mark_context_inactive(context->nsapi); context->network_control_state = SM_NETWORK_DEACTIVATED; } /* +------------------------------------------------------------------------------ | Function : handle_activate_pdp_context_accept +------------------------------------------------------------------------------ | Description : Handle event SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT in S1 | | Parameters : context - Context data | data - T_ACTIVATE_PDP_CONTEXT_ACCEPT * +------------------------------------------------------------------------------ */ static void handle_activate_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_ACTIVATE_PDP_CONTEXT_ACCEPT *msg = (T_ACTIVATE_PDP_CONTEXT_ACCEPT *)data; T_SM_UPDATE_FLAGS update_flags = (T_SM_UPDATE_FLAGS)0; BOOL is_address_changed = FALSE; (void)TRACE_FUNCTION("handle_activate_pdp_context_accept"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Free stored coded message */ sm_free_coded_msg(context); /* Stop timer T3380 */ sm_timer_stop(context); if (!sm_is_llc_sapi_valid(msg->llc_sapi.sapi, context->ti)) { return; } is_address_changed = sm_is_address_changed_with_reactivation(context, &msg->address, msg->v_address); /* Check whether negotiated QoS satisfies minimum QoS */ if ( sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos) && !(is_address_changed) ) { if (context->accepted_qos.ctrl_qos != PS_is_qos_not_present) { update_flags |= SM_UPDATE_QOS; } /* QoS >= minimum QoS: Store negotiated parameters */ sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos); /* Store GSM RAT parameters */ context->radio_prio = msg->radio_prio.radio_prio_val; context->sapi = msg->llc_sapi.sapi; /* Store PFI, if present */ if (msg->v_pfi != (U8)FALSE) { sm_set_pfi_included(context, TRUE); context->pfi = msg->pfi.pfi_val; } else { sm_set_pfi_included(context, FALSE); } /* Store negotiated IP address, if any */ sm_nw_store_negotiated_address(context, &msg->address, msg->v_address); /* Store negotiated PCO, if any */ if (msg->v_pco != (U8)FALSE && msg->pco.c_pco_value > (U8)0) { sm_nw_allocate_and_copy_negotiated_pco(context, msg->pco.c_pco_value, msg->pco.pco_value); } else { context->negotiated_pco = NULL; } /* Check whether to add TFT */ if (sm_tft_more_to_modify(context)) { /* Start T3381 */ sm_timer_start(context, SM_TIMER_T3381); /* Send MODIFY PDP CONTEXT REQUEST with remaining TFTs */ send_msg_modify_pdp_context_request(context); /* Go to state SM NETWORK ACTIVATING ADDING TFTS */ context->network_control_state = SM_NETWORK_ACTIVATING_ADDING_TFTS; } else { /* No TFT: go to state SM NETWORK ACTIVATED, and inform Context Control */ context->network_control_state = SM_NETWORK_ACTIVATED; sm_context_control(context, SM_I_NETWORK_ACTIVATE_COMPLETED, (void *)update_flags); } } else { /* if (sm_qos_is_minimum_satisfied_by_aim()) */ /* Minimum QoS not satisfied - Start deactivation, T3390 */ sm_timer_start(context, SM_TIMER_T3390); /* Send DEACTIVATE PDP CONTEXT REQUEST message */ if (is_address_changed) { sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION); sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION); } else { sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); } send_msg_deactivate_pdp_context_request(context, sm_get_nw_cause(context), FALSE); /* Go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Report failed activation to Context Control (with network deactivation) */ sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE); } /* if */ } /* +------------------------------------------------------------------------------ | Function : handle_activate_pdp_context_reject +------------------------------------------------------------------------------ | Description : Handle event SM_M_ACTIVATE_PDP_CONTEXT_REJECT in S1 | | Parameters : context - Context data | data - T_ACTIVATE_PDP_CONTEXT_REJECT * +------------------------------------------------------------------------------ */ static void handle_activate_pdp_context_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_ACTIVATE_PDP_CONTEXT_REJECT *msg = (T_ACTIVATE_PDP_CONTEXT_REJECT *)data; (void)TRACE_FUNCTION("handle_activate_pdp_context_reject"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Free stored coded message */ sm_free_coded_msg(context); /* Store erroneous PCO, if any */ if (msg->v_pco != (U8)FALSE && msg->pco.c_pco_value > (U8)0) { sm_nw_allocate_and_copy_negotiated_pco(context, msg->pco.c_pco_value, msg->pco.pco_value); } else { context->negotiated_pco = NULL; } /* Stop timer T3380 */ sm_timer_stop(context); /* Go to state SM NETWORK DEACTIVATED */ context->network_control_state = SM_NETWORK_DEACTIVATED; /* Mark context as inactive */ sm_nw_mark_context_inactive(context->nsapi); /* Build cause structure */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val); /* Re-synchronise MMs PDP context status */ send_mmpm_pdp_context_status_req(); /* Report failed activation to Context Control (no network deactivation) */ sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)FALSE); } /* +------------------------------------------------------------------------------ | Function : handle_activate_secondary_pdp_context_accept +------------------------------------------------------------------------------ | Description : Handle event SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT | | Parameters : context - Context data | data - T_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT * +------------------------------------------------------------------------------ */ static void handle_activate_secondary_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT *msg = (T_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT *)data; (void)TRACE_FUNCTION("handle_activate_secondary_pdp_context_accept"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Free stored coded message */ sm_free_coded_msg(context); /* Stop timer T3380 */ sm_timer_stop(context); if (!sm_is_llc_sapi_valid(msg->llc_sapi.sapi, context->ti)) { return; } /* Check whether negotiated QoS satisfies minimum QoS */ if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos)) { /* QoS >= minimum QoS: Store negotiated parameters */ sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos); /* Store GSM RAT parameters */ context->radio_prio = msg->radio_prio.radio_prio_val; context->sapi = msg->llc_sapi.sapi; /* Store PFI, if present */ if (msg->v_pfi != (U8)FALSE) { sm_set_pfi_included(context, TRUE); context->pfi = msg->pfi.pfi_val; } else { sm_set_pfi_included(context, FALSE); } /* Check whether to add TFT */ if (sm_tft_more_to_modify(context)) { /* Start T3381 */ sm_timer_start(context, SM_TIMER_T3381); /* Send MODIFY PDP CONTEXT REQUEST with remaining TFTs */ send_msg_modify_pdp_context_request(context); /* Go to state SM NETWORK ACTIVATING ADDING TFTS */ context->network_control_state = SM_NETWORK_ACTIVATING_ADDING_TFTS; } else { /* No TFT: go to state SM NETWORK ACTIVATED, and inform Context Control */ context->network_control_state = SM_NETWORK_ACTIVATED; sm_context_control(context, SM_I_NETWORK_ACTIVATE_COMPLETED, NULL); } } else { /* if (sm_qos_is_minimum_satisfied_by_aim()) */ /* Minimum QoS not satisfied - go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Start deactivation, T3390 */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); /* Report failed activation to Context Control (with network deactivation) */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE); } /* if */ } /* +------------------------------------------------------------------------------ | Function : handle_activate_secondary_pdp_context_reject +------------------------------------------------------------------------------ | Description : Handle event SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT | | Parameters : context - Context data | data - T_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT * +------------------------------------------------------------------------------ */ static void handle_activate_secondary_pdp_context_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT *msg = (T_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT *)data; (void)TRACE_FUNCTION("handle_activate_secondary_pdp_context_reject"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Free stored coded message */ sm_free_coded_msg(context); /* Stop timer T3380 */ sm_timer_stop(context); /* Go to state SM NETWORK DEACTIVATED */ context->network_control_state = SM_NETWORK_DEACTIVATED; /* Mark context as inactive */ sm_nw_mark_context_inactive(context->nsapi); /* Build cause structure */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val); /* Re-synchronise MMs PDP context status */ send_mmpm_pdp_context_status_req(); /* Report failed activation to Context Control (no network deactivation) */ sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)FALSE); } /* +------------------------------------------------------------------------------ | Function : handle_request_pdp_context_activation_in_S0 +------------------------------------------------------------------------------ | Description : Handle event SM_M_REQUEST_PDP_CONTEXT_ACTIVATION in S0 | | Parameters : context - Context data | data - T_REQUEST_PDP_CONTEXT_ACTIVATION * +------------------------------------------------------------------------------ */ static void handle_request_pdp_context_activation_in_S0(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_REQUEST_PDP_CONTEXT_ACTIVATION *msg = (T_REQUEST_PDP_CONTEXT_ACTIVATION *)data; (void)TRACE_FUNCTION("handle_request_pdp_context_activation_in_S0"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; context->pdp_type = msg->address.pdp_type_no; sm_nw_store_negotiated_address(context, &msg->address, (U8)TRUE); if (msg->v_apn != (U8)FALSE) { sm_nw_allocate_and_copy_apn(context, msg->apn.c_apn_value, msg->apn.apn_value); } else { context->apn = NULL; } /* Inform Context Control of activation request */ sm_context_control(context, SM_I_NETWORK_REQUEST_ACTIVATION, msg); } /* +------------------------------------------------------------------------------ | Function : handle_request_pdp_context_activation_in_S1 +------------------------------------------------------------------------------ | Description : Handle event SM_M_REQUEST_PDP_CONTEXT_ACTIVATION in S1 | | Parameters : context - Context data | data - T_REQUEST_PDP_CONTEXT_ACTIVATION * +------------------------------------------------------------------------------ */ static void handle_request_pdp_context_activation_in_S1(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_REQUEST_PDP_CONTEXT_ACTIVATION *msg = (T_REQUEST_PDP_CONTEXT_ACTIVATION *)data; (void)TRACE_FUNCTION("handle_request_pdp_context_activation_in_S1"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /*lint !e613 (Warning -- Possible use of null pointer) */ if (sm_nw_is_address_and_apn_equal(context, &context->requested_address, &msg->address, msg->v_apn, &msg->apn)) { /* Do nothing */ } else { /* Reject incoming context activation */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_INSUFFICIENT_RESOURCES); send_msg_request_pdp_context_activation_reject(context, sm_get_nw_cause(context)); } /* if */ } /* +------------------------------------------------------------------------------ | Function : handle_request_pdp_context_activation_in_S4 +------------------------------------------------------------------------------ | Description : Handle event SM_M_REQUEST_PDP_CONTEXT_ACTIVATION in S4 | | Parameters : context - Context data | data - T_REQUEST_PDP_CONTEXT_ACTIVATION * +------------------------------------------------------------------------------ */ static void handle_request_pdp_context_activation_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_REQUEST_PDP_CONTEXT_ACTIVATION *msg = (T_REQUEST_PDP_CONTEXT_ACTIVATION *)data; (void)TRACE_FUNCTION("handle_request_pdp_context_activation_in_S4"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; if (sm_nw_is_address_and_apn_equal(context, &context->negotiated_address, &msg->address, msg->v_apn, &msg->apn)) { /* Go to state SM NETWORK ACTIVATING PRIMARY */ context->network_control_state = SM_NETWORK_ACTIVATING_PRIMARY; /* Inform Context Control of the activation override * NOTE! Normally other state machines are informed last, but in this * case we need to update sm_data.sm_context_activation_status _before_ * sending ACTIVATE PDP CONTEXT REQUEST through MM. */ sm_context_control(context, SM_I_NETWORK_REQUEST_ACTIVATION_OVERRIDE, NULL); /* Context activation override - start context activation procedure */ sm_timer_start(context, SM_TIMER_T3380); /* This is akin to a context reactivation: Use currently negotiated IP address */ sm_nw_copy_negotiated_address_to_requested(context); send_msg_activate_pdp_context_request(context); } else { /* Reject incoming context activation */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_INSUFFICIENT_RESOURCES); send_msg_request_pdp_context_activation_reject(context, sm_get_nw_cause(context)); } /* if */ } /* +------------------------------------------------------------------------------ | Function : handle_modify_pdp_context_request_in_S3 +------------------------------------------------------------------------------ | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REQUEST in S3 | | Parameters : context - Context data | data - T_MODIFY_PDP_CONTEXT_REQUEST * (unused) +------------------------------------------------------------------------------ */ static void handle_modify_pdp_context_request_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data) { (void)TRACE_FUNCTION("handle_modify_pdp_context_request_in_S3"); /* Free coded message */ sm_free_coded_msg(context); /* Stop T3381, start T3390, and send DEACTIVATE PDP CONTEXT REQUEST message */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_MSG_INCOMPATIBLE_WITH_STATE); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); /* Go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Inform Context Control of the failed activation (with network deactivation) */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_MSG_INCOMPATIBLE_WITH_STATE); sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE); } /* +------------------------------------------------------------------------------ | Function : handle_modify_pdp_context_request_in_S4 +------------------------------------------------------------------------------ | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REQUEST in S4 | | Parameters : context - Context data | data - T_D_MODIFY_PDP_CONTEXT_REQUEST * +------------------------------------------------------------------------------ */ static void handle_modify_pdp_context_request_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_D_MODIFY_PDP_CONTEXT_REQUEST *msg = (T_D_MODIFY_PDP_CONTEXT_REQUEST *)data; T_SM_UPDATE_FLAGS update_flags; (void)TRACE_FUNCTION("handle_modify_pdp_context_request_in_S4"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; if (!sm_is_llc_sapi_valid(msg->llc_sapi.sapi, context->ti)) { return; } if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos)) { /* QoS >= minimum QoS: Store negotiated parameters */ update_flags = sm_nw_store_mt_modify_parameters(context, msg); /* Go to state SM NETWORK ACTIVATED */ context->network_control_state = SM_NETWORK_ACTIVATED; /* Reply to network: MODIFY PDP CONTEXT ACCEPT */ send_msg_modify_pdp_context_accept(context); /* Report successful NW initiated context modification */ sm_context_control(context, SM_I_NETWORK_REQUEST_MODIFY, (void *)update_flags); } else { /* Minimum QoS not satisfied - go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Start deactivation, T3390 */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); /* Report failed activation to Context Control */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_context_control(context, SM_I_NETWORK_REQUEST_MODIFY_FAILED, NULL); } /* if (sm_qos_is_minimum_satisfied_by_aim()) */ } /* +------------------------------------------------------------------------------ | Function : handle_modify_pdp_context_request_in_S5 +------------------------------------------------------------------------------ | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REQUEST in S5 | | Parameters : context - Context data | data - T_D_MODIFY_PDP_CONTEXT_REQUEST * +------------------------------------------------------------------------------ */ static void handle_modify_pdp_context_request_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_D_MODIFY_PDP_CONTEXT_REQUEST *msg = (T_D_MODIFY_PDP_CONTEXT_REQUEST *)data; T_SM_UPDATE_FLAGS update_flags; (void)TRACE_FUNCTION("handle_modify_pdp_context_request_in_S5"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Free coded message */ sm_free_coded_msg(context); /* Reject currently active UE initiated modification */ sm_set_aci_cause(context, CAUSE_is_from_sm, (U16)CAUSE_SM_MODIFY_COLLISION); sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)FALSE); if (!sm_is_llc_sapi_valid(msg->llc_sapi.sapi, context->ti)) { return; } if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos)) { /* QoS >= minimum QoS: Store negotiated parameters */ update_flags = sm_nw_store_mt_modify_parameters(context, msg); /* Go to state SM NETWORK ACTIVATED */ context->network_control_state = SM_NETWORK_ACTIVATED; /* Reply to network: MODIFY PDP CONTEXT ACCEPT */ send_msg_modify_pdp_context_accept(context); /* Report successful NW initiated context modification */ sm_context_control(context, SM_I_NETWORK_REQUEST_MODIFY, (void *)update_flags); } else { /* Minimum QoS not satisfied - go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Start deactivation, T3390 */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); /* Report failed activation to Context Control */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_context_control(context, SM_I_NETWORK_REQUEST_MODIFY_FAILED, NULL); } /* if (sm_qos_is_minimum_satisfied_by_aim()) */ } /* +------------------------------------------------------------------------------ | Function : handle_modify_pdp_context_request_in_S6 +------------------------------------------------------------------------------ | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REQUEST in S6 | | Parameters : context - Context data | data - T_MODIFY_PDP_CONTEXT_REQUEST * (unused) +------------------------------------------------------------------------------ */ static void handle_modify_pdp_context_request_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/ void *data) { (void)TRACE_FUNCTION("handle_modify_pdp_context_request_in_S6"); /* Free coded message */ sm_free_coded_msg(context); /* Reject currently active UE initiated modification */ sm_set_aci_cause(context, CAUSE_is_from_sm, (U16)CAUSE_SM_MODIFY_COLLISION); sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)FALSE); /* Go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Stop T3381, start T3390, and send DEACTIVATE PDP CONTEXT REQUEST message */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_MSG_INCOMPATIBLE_WITH_STATE); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); /* Inform Context Control of the failed modification */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_MSG_INCOMPATIBLE_WITH_STATE); sm_context_control(context, SM_I_NETWORK_REQUEST_MODIFY_FAILED, NULL); } /* +------------------------------------------------------------------------------ | Function : handle_modify_pdp_context_accept_in_S3 +------------------------------------------------------------------------------ | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_ACCEPT in S3 | | Parameters : context - Context data | data - T_D_MODIFY_PDP_CONTEXT_ACCEPT * +------------------------------------------------------------------------------ */ static void handle_modify_pdp_context_accept_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_D_MODIFY_PDP_CONTEXT_ACCEPT *msg = (T_D_MODIFY_PDP_CONTEXT_ACCEPT *)data; T_SM_UPDATE_FLAGS update_flags; (void)TRACE_FUNCTION("handle_modify_pdp_context_accept_in_S3"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Free stored coded message */ sm_free_coded_msg(context); /* Stop timer T3381 */ sm_timer_stop(context); /* Store GSM RAT parameters, if present */ update_flags = sm_nw_store_modify_accept_parameters(context, msg); if (msg->v_qos != (U8)FALSE) { update_flags |= SM_UPDATE_QOS; /* We requested no new QoS, but received one nontheless. */ if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos)) { /* QoS >= minimum QoS: Store negotiated parameters */ sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos); } else { /* Minimum QoS no longer satisfied: Abort activation */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); context->network_control_state = SM_NETWORK_DEACTIVATING; sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); /* Report failed activation to Context Control (with network deactivation) */ sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE); return; } /* if (sm_qos_is_minimum_satisfied_by_aim) */ } if (sm_tft_more_to_modify(context)) { /* Start T3381 */ sm_timer_start(context, SM_TIMER_T3381); /* Send MODIFY PDP CONTEXT REQUEST with remaining TFTs */ send_msg_modify_pdp_context_request(context); } else { /* No more TFTs to add: go to state SM NETWORK ACTIVATED, and inform Context Control */ context->network_control_state = SM_NETWORK_ACTIVATED; sm_context_control(context, SM_I_NETWORK_ACTIVATE_COMPLETED, (void *)update_flags); } } /* +------------------------------------------------------------------------------ | Function : handle_modify_pdp_context_accept_in_S5 +------------------------------------------------------------------------------ | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_ACCEPT in S5 | | Parameters : context - Context data | data - T_D_MODIFY_PDP_CONTEXT_ACCEPT * +------------------------------------------------------------------------------ */ static void handle_modify_pdp_context_accept_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_D_MODIFY_PDP_CONTEXT_ACCEPT *msg = (T_D_MODIFY_PDP_CONTEXT_ACCEPT *)data; T_SM_UPDATE_FLAGS update_flags = (T_SM_UPDATE_FLAGS)0; (void)TRACE_FUNCTION("handle_modify_pdp_context_accept_in_S5"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Free stored coded message */ sm_free_coded_msg(context); /* Stop timer T3381 */ sm_timer_stop(context); /* Store GSM RAT parameters, if present */ update_flags = sm_nw_store_modify_accept_parameters(context, msg); if (msg->v_qos != (U8)FALSE) { /* QoS updated */ if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos)) { /* QoS >= minimum QoS: Store negotiated parameters */ sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos); update_flags |= SM_UPDATE_QOS; } else { /* Minimum QoS no longer satisfied: Deactivate */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); context->network_control_state = SM_NETWORK_DEACTIVATING; sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)FALSE); return; } /* if (sm_qos_is_minimum_satisfied_by_aim) */ } else { /* Check that minimum QoS is still satisfied by current QoS */ if (!sm_qos_is_minimum_satisfied_by_sm(context, &context->accepted_qos)) { /* Minimum QoS no longer satisfied: Deactivate */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); context->network_control_state = SM_NETWORK_DEACTIVATING; sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)TRUE); return; } } if (sm_tft_more_to_modify(context)) { /* Start T3381 */ sm_timer_start(context, SM_TIMER_T3381); /* Send MODIFY PDP CONTEXT REQUEST with more TFTs */ send_msg_modify_pdp_context_request(context); context->network_control_state = SM_NETWORK_MODIFYING_ADDITIONAL_TFTS; } else { /* No more TFTs to add: Modification completed. */ /* Go to state SM NETWORK ACTIVATED, and inform Context Control */ context->network_control_state = SM_NETWORK_ACTIVATED; sm_context_control(context, SM_I_NETWORK_MODIFY_COMPLETED, (void *)update_flags); } } /* +------------------------------------------------------------------------------ | Function : handle_modify_pdp_context_accept_in_S6 +------------------------------------------------------------------------------ | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_ACCEPT in S6 | | Parameters : context - Context data | data - T_D_MODIFY_PDP_CONTEXT_ACCEPT * +------------------------------------------------------------------------------ */ static void handle_modify_pdp_context_accept_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_D_MODIFY_PDP_CONTEXT_ACCEPT *msg = (T_D_MODIFY_PDP_CONTEXT_ACCEPT *)data; T_SM_UPDATE_FLAGS update_flags = (T_SM_UPDATE_FLAGS)0; (void)TRACE_FUNCTION("handle_modify_pdp_context_accept_in_S6"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Free stored coded message */ sm_free_coded_msg(context); /* Stop timer T3381 */ sm_timer_stop(context); /* Store GSM RAT parameters, if present */ update_flags = sm_nw_store_modify_accept_parameters(context, msg); if (msg->v_qos != (U8)FALSE) { /* We requested no new QoS, but received one nontheless. */ if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos)) { /* QoS >= minimum QoS: Store negotiated parameters */ sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos); update_flags |= SM_UPDATE_QOS; } else { /* Minimum QoS no longer satisfied: Deactivate */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); context->network_control_state = SM_NETWORK_DEACTIVATING; sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED); sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)TRUE); return; } /* if (sm_qos_is_minimum_satisfied_by_aim) */ } if (sm_tft_more_to_modify(context)) { /* Start T3381 */ sm_timer_start(context, SM_TIMER_T3381); /* Send MODIFY PDP CONTEXT REQUEST with remaining TFTs */ send_msg_modify_pdp_context_request(context); } else { /* No more TFTs to add: Modification completed. */ /* Go to state SM NETWORK ACTIVATED, and inform Context Control */ context->network_control_state = SM_NETWORK_ACTIVATED; sm_context_control(context, SM_I_NETWORK_MODIFY_COMPLETED, (void *)update_flags); } } /* +------------------------------------------------------------------------------ | Function : handle_modify_pdp_context_reject_in_S3 +------------------------------------------------------------------------------ | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REJECT in S3 | | Parameters : context - Context data | data - T_MODIFY_PDP_CONTEXT_REJECT * +------------------------------------------------------------------------------ */ static void handle_modify_pdp_context_reject_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_MODIFY_PDP_CONTEXT_REJECT *msg = (T_MODIFY_PDP_CONTEXT_REJECT *)data; (void)TRACE_FUNCTION("handle_modify_pdp_context_reject_in_S3"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Free stored coded message */ sm_free_coded_msg(context); /* Go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Save cause value for ACI */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val); /* Stop T3381, start T3390, and send DEACTIVATE PDP CONTEXT REQUEST message */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); /* Inform Context Control of the failed activation (with network deactivation) */ sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE); } /* +------------------------------------------------------------------------------ | Function : handle_modify_pdp_context_reject_in_S5 +------------------------------------------------------------------------------ | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REJECT in S5 | | Parameters : context - Context data | data - T_MODIFY_PDP_CONTEXT_REJECT * +------------------------------------------------------------------------------ */ static void handle_modify_pdp_context_reject_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_MODIFY_PDP_CONTEXT_REJECT *msg = (T_MODIFY_PDP_CONTEXT_REJECT *)data; (void)TRACE_FUNCTION("handle_modify_pdp_context_reject_in_S5"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Free stored coded message */ sm_free_coded_msg(context); /* Go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Save cause value for ACI */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val); /* Stop T3381, start T3390, and send DEACTIVATE PDP CONTEXT REQUEST message */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); /* Inform Context Control of the failed modification */ sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)TRUE); } /* +------------------------------------------------------------------------------ | Function : handle_modify_pdp_context_reject_in_S6 +------------------------------------------------------------------------------ | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REJECT in S6 | | Parameters : context - Context data | data - T_MODIFY_PDP_CONTEXT_REJECT * +------------------------------------------------------------------------------ */ static void handle_modify_pdp_context_reject_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_MODIFY_PDP_CONTEXT_REJECT *msg = (T_MODIFY_PDP_CONTEXT_REJECT *)data; (void)TRACE_FUNCTION("handle_modify_pdp_context_reject_in_S6"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Free stored coded message */ sm_free_coded_msg(context); /* Go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Save cause value for ACI */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val); /* Stop T3381, start T3390, and send DEACTIVATE PDP CONTEXT REQUEST message */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); /* Inform Context Control of the failed modification */ sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)TRUE); } /* +------------------------------------------------------------------------------ | Function : handle_deactivate_pdp_context_request_while_active +------------------------------------------------------------------------------ | Description : Handle event SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST in S1 - S6 | | Parameters : context - Context data | data - T_DEACTIVATE_PDP_CONTEXT_REQUEST * +------------------------------------------------------------------------------ */ static void handle_deactivate_pdp_context_request_while_active(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { BOOL tear_down; T_DEACTIVATE_PDP_CONTEXT_REQUEST *msg = (T_DEACTIVATE_PDP_CONTEXT_REQUEST *)data; (void)TRACE_FUNCTION("handle_deactivate_pdp_context_request_while_active"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Stop any active timers */ sm_timer_stop(context); /* Free stored coded message - if any */ sm_free_coded_msg(context); if (msg->v_tear_down != (U8)FALSE && msg->tear_down.tear_down_flag == (U8)1) { tear_down = TRUE; /* Mark linked contexts as inactive */ sm_nw_mark_nsapi_set_inactive(sm_linked_nsapis(context->ti)); } else { tear_down = FALSE; }; /* Mark context as inactive */ sm_nw_mark_context_inactive(context->nsapi); /* Save cause for ACI */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val); /* Send DEACTIVATE PDP CONTEXT ACCEPT message */ send_msg_deactivate_pdp_context_accept(context); /* Go to state SM NETWORK DEACTIVATED */ context->network_control_state = SM_NETWORK_DEACTIVATED; /* Report deactivation to Context Control */ sm_context_control(context, SM_I_NETWORK_REQUEST_DEACTIVATE, (void *)tear_down); } /* +------------------------------------------------------------------------------ | Function : handle_deactivate_pdp_context_request_while_deactivating +------------------------------------------------------------------------------ | Description : Handle event SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST in S7 | | Parameters : context - Context data | data - T_DEACTIVATE_PDP_CONTEXT_REQUEST * +------------------------------------------------------------------------------ */ static void handle_deactivate_pdp_context_request_while_deactivating(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data) { T_DEACTIVATE_PDP_CONTEXT_REQUEST *msg = (T_DEACTIVATE_PDP_CONTEXT_REQUEST *)data; (void)TRACE_FUNCTION("handle_deactivate_pdp_context_request_while_deactivating"); TRACE_ASSERT(msg != NULL); if (msg EQ NULL) return; /* Save cause for ACI */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val); /* Send DEACTIVATE PDP CONTEXT ACCEPT message */ send_msg_deactivate_pdp_context_accept(context); /* Report deactivation to Context Control iff tear_down == TRUE */ if (msg->v_tear_down != (U8)FALSE && msg->tear_down.tear_down_flag == (U8)1) { sm_context_control(context, SM_I_NETWORK_REQUEST_DEACTIVATE, (void *)TRUE); } } /* +------------------------------------------------------------------------------ | Function : handle_deactivate_pdp_context_accept +------------------------------------------------------------------------------ | Description : Handle event SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT in S7 | | Parameters : context - Context data | data - Not used +------------------------------------------------------------------------------ */ static void handle_deactivate_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/ void *data) { (void)TRACE_FUNCTION("handle_deactivate_pdp_context_accept"); /* Free stored coded message */ sm_free_coded_msg(context); /* Stop T3390 */ sm_timer_stop(context); /* Go to state SM NETWORK DEACTIVATED */ context->network_control_state = SM_NETWORK_DEACTIVATED; /* Mark context as inactive */ sm_nw_mark_context_inactive(context->nsapi); /* Report deactivate complete to Context Control */ sm_context_control(context, SM_I_NETWORK_DEACTIVATE_COMPLETED, NULL); } /* +------------------------------------------------------------------------------ | Function : handle_T3380 +------------------------------------------------------------------------------ | Description : Handle event SM_T_T3380 | | Parameters : context - Context data | data - Not used +------------------------------------------------------------------------------ */ static void handle_T3380(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data) { (void)TRACE_FUNCTION("handle_T3380"); /* If SM is not suspended, resend ACTIVATE (SECONDARY) PDP CONTEXT REQUEST */ resend_msg(context); } /* +------------------------------------------------------------------------------ | Function : handle_T3380_max +------------------------------------------------------------------------------ | Description : Handle event SM_T_T3380_MAX | | Parameters : context - Context data | data - Not used +------------------------------------------------------------------------------ */ static void handle_T3380_max(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data) { (void)TRACE_FUNCTION("handle_T3380_max"); /* Free stored coded message */ sm_free_coded_msg(context); /* Go to state SM NETWORK DEACTIVATED */ context->network_control_state = SM_NETWORK_DEACTIVATED; /* Inform Context Control of the failed activation (no network deactivation) */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_NETWORK_FAILURE); sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)FALSE); } /* +------------------------------------------------------------------------------ | Function : handle_T3381 +------------------------------------------------------------------------------ | Description : Handle event SM_T_T3381 | | Parameters : context - Context data | data - Not used +------------------------------------------------------------------------------ */ static void handle_T3381(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data) { (void)TRACE_FUNCTION("handle_T3381"); /* If SM is not suspended, resend MODIFY PDP CONTEXT REQUEST */ resend_msg(context); } /* +------------------------------------------------------------------------------ | Function : handle_T3381_max_in_S3 +------------------------------------------------------------------------------ | Description : Handle event SM_T_T3381_MAX in S3 | | Parameters : context - Context data | data - Not used +------------------------------------------------------------------------------ */ static void handle_T3381_max_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data) { (void)TRACE_FUNCTION("handle_T3381_max_in_S3"); /* Free stored coded message */ sm_free_coded_msg(context); /* Go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Initiate deactivation */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); /* Inform Context Control of the failed activation */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_NETWORK_FAILURE); sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE); } /* +------------------------------------------------------------------------------ | Function : handle_T3381_max_in_S5 +------------------------------------------------------------------------------ | Description : Handle event SM_T_T3381_MAX in S5 | | Parameters : context - Context data | data - Not used +------------------------------------------------------------------------------ */ static void handle_T3381_max_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data) { (void)TRACE_FUNCTION("handle_T3381_max_in_S5"); /* Free stored coded message */ sm_free_coded_msg(context); /* Modify procedure has failed, but the context remains active. */ /* Go to state SM NETWORK ACTIVATED */ context->network_control_state = SM_NETWORK_ACTIVATED; /* Inform Context Control of the failed activation */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_NETWORK_FAILURE); sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)FALSE); } /* +------------------------------------------------------------------------------ | Function : handle_T3381_max_in_S6 +------------------------------------------------------------------------------ | Description : Handle event SM_T_T3381_MAX in S6 | | Parameters : context - Context data | data - Not used +------------------------------------------------------------------------------ */ static void handle_T3381_max_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data) { (void)TRACE_FUNCTION("handle_T3381_max_in_S6"); /* Free stored coded message */ sm_free_coded_msg(context); /* Go to state SM NETWORK DEACTIVATING */ context->network_control_state = SM_NETWORK_DEACTIVATING; /* Initiate deactivation */ sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION); sm_nw_initiate_deactivation(context, sm_get_nw_cause(context)); /* Inform Context Control of the failed activation */ sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_NETWORK_FAILURE); sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)TRUE); } /* +------------------------------------------------------------------------------ | Function : handle_T3390 +------------------------------------------------------------------------------ | Description : Handle event SM_T_T3390 | | Parameters : context - Context data | data - Not used +------------------------------------------------------------------------------ */ static void handle_T3390(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data) { (void)TRACE_FUNCTION("handle_T3390"); /* If SM is not suspended, resend DEACTIVATE PDP CONTEXT REQUEST */ resend_msg(context); } /* +------------------------------------------------------------------------------ | Function : handle_T3390_max +------------------------------------------------------------------------------ | Description : Handle event SM_T_T3390_MAX | | Parameters : context - Context data | data - Not used +------------------------------------------------------------------------------ */ static void handle_T3390_max(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data) { (void)TRACE_FUNCTION("handle_T3390_max"); /* Free stored coded message */ sm_free_coded_msg(context); /* Go to state SM NETWORK DEACTIVATED */ context->network_control_state = SM_NETWORK_DEACTIVATED; /* Context is considered deactivated. Inform Context Control. */ sm_context_control(context, SM_I_NETWORK_DEACTIVATE_COMPLETED, NULL); } /* +------------------------------------------------------------------------------ | Function : handle_mmpm_suspend_ind +------------------------------------------------------------------------------ | Description : Handle incoming MMPM_SUSPEND_IND primitive | | Parameters : context - Context data | data - Unused +------------------------------------------------------------------------------ */ static void handle_mmpm_suspend_ind(/*@unused@*/struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/ void *data) { (void)TRACE_FUNCTION("handle_mmpm_suspend_ind"); } /* +------------------------------------------------------------------------------ | Function : handle_mmpm_resume_ind +------------------------------------------------------------------------------ | Description : Handle incoming MMPM_RESUME_IND primitive | | Parameters : context - Context data | data - Unused +------------------------------------------------------------------------------ */ static void handle_mmpm_resume_ind(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/ void *data) { (void)TRACE_FUNCTION("handle_mmpm_resume_ind"); if (sm_is_started_during_suspend(context)) { resend_msg(context); sm_clear_started_during_suspend(context); } } /*==== PUBLIC FUNCTIONS =====================================================*/ /* +------------------------------------------------------------------------------ | Function : sm_network_control_init +------------------------------------------------------------------------------ | Description : Network Control state machine initialization function | Parameters : context - Context data +------------------------------------------------------------------------------ */ void sm_network_control_init(struct T_SM_CONTEXT_DATA *context) { (void)TRACE_FUNCTION("sm_network_control_init"); context->network_control_state = SM_NETWORK_DEACTIVATED; } /* +------------------------------------------------------------------------------ | Function : sm_network_control_exit +------------------------------------------------------------------------------ | Description : Network Control state machine exit function | Parameters : context - Context data +------------------------------------------------------------------------------ */ void sm_network_control_exit(struct T_SM_CONTEXT_DATA *context) { (void)TRACE_FUNCTION("sm_network_control_exit"); context->network_control_state = SM_NETWORK_DEACTIVATED; /* Free any memory allocated to this context (fields managed by Network Control) */ sm_free_coded_msg(context); sm_nw_free_apn(context); sm_nw_free_requested_tft(context); sm_nw_free_active_tft(context); sm_nw_free_requested_pco(context); sm_nw_free_negotiated_pco(context); } /* +------------------------------------------------------------------------------ | Function : sm_network_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_network_control_state(struct T_SM_CONTEXT_DATA *context) { /*@observer@*/ static const char *state_name[SM_NETWORK_CONTROL_NUMBER_OF_STATES] = { "S0_SM_NETWORK_DEACTIVATED", "S1_SM_NETWORK_ACTIVATING_PRIMARY", "S2_SM_NETWORK_ACTIVATING_SECONDARY", "S3_SM_NETWORK_ACTIVATING_ADDING_TFTS", "S4_SM_NETWORK_ACTIVATED", "S5_SM_NETWORK_MODIFYING", "S6_SM_NETWORK_MODIFYING_ADDITIONAL_TFTS", "S7_SM_NETWORK_DEACTIVATING" }; TRACE_ASSERT(context->network_control_state < SM_NETWORK_CONTROL_NUMBER_OF_STATES); return state_name[(U16)context->network_control_state]; } #endif /* +------------------------------------------------------------------------------ | Function : sm_network_control +------------------------------------------------------------------------------ | Description : User Plane Control state machine | | Parameters : context - Context data | event - Internal event (see sm_network_control.h) | data - Event dependent parameter +------------------------------------------------------------------------------ */ void sm_network_control(struct T_SM_CONTEXT_DATA *context, T_SM_NETWORK_CONTROL_EVENT event, /*@null@*/ void *data) { #ifdef DEBUG const char *old_state_name, *new_state_name; T_SM_NETWORK_CONTROL_STATE old_state; /*@observer@*/ static const char *event_name[SM_NETWORK_CONTROL_NUMBER_OF_EVENTS] = { "SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT", "SM_M_ACTIVATE_PDP_CONTEXT_REJECT", "SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT", "SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT", "SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST", "SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT", "SM_M_MODIFY_PDP_CONTEXT_REQUEST", "SM_M_MODIFY_PDP_CONTEXT_ACCEPT", "SM_M_MODIFY_PDP_CONTEXT_REJECT", "SM_M_REQUEST_PDP_CONTEXT_ACTIVATION", "SM_M_SM_STATUS", "SM_P_MMPM_RESUME_IND", "SM_P_MMPM_SUSPEND_IND", "SM_T_T3380", "SM_T_T3380_MAX", "SM_T_T3381", "SM_T_T3381_MAX", "SM_T_T3390", "SM_T_T3390_MAX", "SM_I_NETWORK_ACTIVATE_PRIMARY", "SM_I_NETWORK_ACTIVATE_SECONDARY", "SM_I_NETWORK_DEACTIVATE_LOCAL", "SM_I_NETWORK_MODIFY", "SM_I_NETWORK_REQUEST_ACTIVATION_REJECT", "SM_I_NETWORK_DEACTIVATE" }; TRACE_ASSERT(event < SM_NETWORK_CONTROL_NUMBER_OF_EVENTS); old_state = context->network_control_state; old_state_name = sm_network_control_state(context); if (transition[(U16)old_state][(U16)event].event != event) { (void)TRACE_ERROR("Event table error in sm_network_control!"); } #endif /* DEBUG */ transition[(U16)context->network_control_state][(U16)event].func(context, data); #ifdef DEBUG new_state_name = sm_network_control_state(context); (void)TRACE_EVENT_P4("SM NETWORK #%d: %s => %s to %s", context->nsapi, event_name[(U16)event], old_state_name, new_state_name); #endif /* DEBUG */ } /*==== END OF FILE ==========================================================*/