/**************************************************************************** ** ** ** Name: esm_proc_dedicated_eps_bearer_context_reject() ** ** ** ** Description: Performs dedicated EPS bearer context activation proce- ** ** dure not accepted by the UE. ** ** ** ** 3GPP TS 24.301, section 6.4.2.4 ** ** The UE rejects dedicated EPS bearer context activation by ** ** sending ACTIVATE DEDICATED EPS BEARER CONTEXT REJECT mes- ** ** sage. ** ** ** ** Inputs: is_standalone: Not used ** ** ebi: EPS bearer identity ** ** msg: Encoded ESM message to be sent ** ** ue_triggered: Not used ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; int rc = RETURNok; LOG_TRACE(WARNING, "ESM-PROC - Dedicated EPS bearer context activation " "not accepted by the UE (ebi=%d)", ebi); if ( !esm_ebr_is_not_in_use(ebi) ) { /* Release EPS bearer data currently in use */ rc = esm_ebr_release(ebi); } if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release EPS bearer data"); } else { emm_sap_t emm_sap; emm_esm_data_t *emm_esm = &emm_sap.u.emm_esm.u.data; /* * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; rc = emm_sap_send(&emm_sap); } LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _authentication_reject() ** ** ** ** Description: Sends AUTHENTICATION REJECT message ** ** ** ** Inputs: ueid: UE lower layer identifier ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ static int _authentication_reject(unsigned int ueid) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; struct emm_data_context_s *emm_ctx; /* * Notify EMM-AS SAP that Authentication Reject message has to be sent * to the UE */ emm_sap.primitive = EMMAS_SECURITY_REJ; emm_sap.u.emm_as.u.security.guti = NULL; emm_sap.u.emm_as.u.security.ueid = ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH; #if defined(NAS_BUILT_IN_EPC) emm_ctx = emm_data_context_get(&_emm_data, ueid); #else emm_ctx = _emm_data.ctx[ueid]; #endif /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, emm_ctx->security, FALSE, TRUE); rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN (rc); }
/******************************************************************** ** ** ** Name: emm_proc_identification() ** ** ** ** Description: Initiates an identification procedure. ** ** ** ** 3GPP TS 24.301, section 5.4.4.2 ** ** The network initiates the identification procedure by ** ** sending an IDENTITY REQUEST message to the UE and star- ** ** ting the timer T3470. The IDENTITY REQUEST message speci- ** ** fies the requested identification parameters in the Iden- ** ** tity type information element. ** ** ** ** Inputs: ueid: UE lower layer identifier ** ** type: Type of the requested identity ** ** success: Callback function executed when the identi- ** ** fication procedure successfully completes ** ** reject: Callback function executed when the identi- ** ** fication procedure fails or is rejected ** ** failure: Callback function executed whener a lower ** ** layer failure occured before the identifi- ** ** cation procedure completes ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: _emm_data ** ** ** ********************************************************************/ int emm_proc_identification(unsigned int ueid, emm_data_context_t *emm_ctx, emm_proc_identity_type_t type, emm_common_success_callback_t success, emm_common_reject_callback_t reject, emm_common_failure_callback_t failure) { LOG_FUNC_IN; int rc = RETURNerror; LOG_TRACE(INFO, "EMM-PROC - Initiate identification type = %s (%d), ctx = %p", _emm_identity_type_str[type], type, emm_ctx); /* Allocate parameters of the retransmission timer callback */ identification_data_t *data = (identification_data_t *)malloc(sizeof(identification_data_t)); if (data != NULL) { /* Setup ongoing EMM procedure callback functions */ rc = emm_proc_common_initialize(ueid, success, reject, failure, _identification_abort, data); if (rc != RETURNok) { LOG_TRACE(WARNING, "Failed to initialize EMM callback functions"); free(data); LOG_FUNC_RETURN (RETURNerror); } /* Set the UE identifier */ data->ueid = ueid; /* Reset the retransmission counter */ data->retransmission_count = 0; /* Set the type of the requested identity */ data->type = type; /* Set the failure notification indicator */ data->notify_failure = FALSE; /* Send identity request message to the UE */ rc = _identification_request(data); if (rc != RETURNerror) { /* * Notify EMM that common procedure has been initiated */ MSC_LOG_TX_MESSAGE( MSC_NAS_EMM_MME, MSC_NAS_EMM_MME, NULL,0, "0 EMMREG_COMMON_PROC_REQ ue id "NAS_UE_ID_FMT" (identification)", ueid); emm_sap_t emm_sap; emm_sap.primitive = EMMREG_COMMON_PROC_REQ; emm_sap.u.emm_reg.ueid = ueid; emm_sap.u.emm_reg.ctx = emm_ctx; rc = emm_sap_send(&emm_sap); } } LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _eps_bearer_deactivate() ** ** ** ** Description: Sends DEACTIVATE EPS BEREAR CONTEXT REQUEST message and ** ** starts timer T3495 ** ** ** ** Inputs: ueid: UE local identifier ** ** ebi: EPS bearer identity ** ** msg: Encoded ESM message to be sent ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: T3495 ** ** ** ***************************************************************************/ static int _eps_bearer_deactivate ( emm_data_context_t * ctx, int ebi, const OctetString * msg) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; /* * Notify EMM that a deactivate EPS bearer context request message * has to be sent to the UE */ emm_esm_data_t *emm_esm = &emm_sap.u.emm_esm.u.data; emm_sap.primitive = EMMESM_UNITDATA_REQ; emm_sap.u.emm_esm.ueid = ctx->ueid; emm_sap.u.emm_esm.ctx = ctx; emm_esm->msg = *msg; rc = emm_sap_send (&emm_sap); if (rc != RETURNerror) { /* * Start T3495 retransmission timer */ rc = esm_ebr_start_timer (ctx, ebi, msg, T3495_DEFAULT_VALUE, _eps_bearer_deactivate_t3495_handler); } LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _authentication_abort() ** ** ** ** Description: Aborts the authentication procedure currently in progress ** ** ** ** Inputs: args: Authentication data to be released ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: T3460 ** ** ** ***************************************************************************/ static int _authentication_abort ( void *args) { LOG_FUNC_IN; int rc = RETURNerror; struct emm_data_context_s *emm_ctx; authentication_data_t *data = (authentication_data_t *) (args); if (data) { unsigned int ueid = data->ueid; int notify_failure = data->notify_failure; LOG_TRACE (WARNING, "EMM-PROC - Abort authentication procedure " "(ueid=" NAS_UE_ID_FMT ")", ueid); #if NAS_BUILT_IN_EPC emm_ctx = emm_data_context_get (&_emm_data, ueid); #else emm_ctx = _emm_data.ctx[ueid]; #endif if (emm_ctx) { /* * Stop timer T3460 */ if (emm_ctx->T3460.id != NAS_TIMER_INACTIVE_ID) { LOG_TRACE (INFO, "EMM-PROC - Stop timer T3460 (%d)", emm_ctx->T3460.id); emm_ctx->T3460.id = nas_timer_stop (emm_ctx->T3460.id); MSC_LOG_EVENT (MSC_NAS_EMM_MME, "0 T3460 stopped UE " NAS_UE_ID_FMT " ", data->ueid); } } /* * Release retransmission timer paramaters */ if (data->rand.length > 0) { free (data->rand.value); } if (data->autn.length > 0) { free (data->autn.value); } free (data); /* * Notify EMM that the authentication procedure failed */ if (notify_failure) { emm_sap_t emm_sap; emm_sap.primitive = EMMREG_COMMON_PROC_REJ; emm_sap.u.emm_reg.ueid = ueid; rc = emm_sap_send (&emm_sap); } else { rc = RETURNok; } } LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _authentication_request() ** ** ** ** Description: Sends AUTHENTICATION REQUEST message and start timer T3460** ** ** ** Inputs: args: handler parameters ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: T3460 ** ** ** ***************************************************************************/ int _authentication_request(authentication_data_t *data) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; struct emm_data_context_s *emm_ctx; /* * Notify EMM-AS SAP that Authentication Request message has to be sent * to the UE */ emm_sap.primitive = EMMAS_SECURITY_REQ; emm_sap.u.emm_as.u.security.guti = NULL; emm_sap.u.emm_as.u.security.ueid = data->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH; emm_sap.u.emm_as.u.security.ksi = data->ksi; emm_sap.u.emm_as.u.security.rand = &data->rand; emm_sap.u.emm_as.u.security.autn = &data->autn; /* TODO: check for pointer validity */ #if defined(NAS_BUILT_IN_EPC) emm_ctx = emm_data_context_get(&_emm_data, data->ueid); #else emm_ctx = _emm_data.ctx[data->ueid]; #endif /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, emm_ctx->security, FALSE, TRUE); MSC_LOG_TX_MESSAGE( MSC_NAS_EMM_MME, MSC_NAS_EMM_MME, NULL,0, "0 EMMAS_SECURITY_REQ ue id "NAS_UE_ID_FMT" ", data->ueid); rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { if (emm_ctx) { if (emm_ctx->T3460.id != NAS_TIMER_INACTIVE_ID) { /* Re-start T3460 timer */ emm_ctx->T3460.id = nas_timer_restart(emm_ctx->T3460.id); MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3460 restarted UE "NAS_UE_ID_FMT" ", data->ueid); } else { /* Start T3460 timer */ emm_ctx->T3460.id = nas_timer_start(emm_ctx->T3460.sec, _authentication_t3460_handler, data); MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3460 started UE "NAS_UE_ID_FMT" ", data->ueid); } } LOG_TRACE(INFO,"EMM-PROC - Timer T3460 (%d) expires in %ld seconds", emm_ctx->T3460.id, emm_ctx->T3460.sec); } LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _identification_request() ** ** ** ** Description: Sends IDENTITY REQUEST message and start timer T3470. ** ** ** ** Inputs: args: handler parameters ** ** Others: None ** ** ** ** Outputs: None ** ** Return: None ** ** Others: T3470 ** ** ** ***************************************************************************/ int _identification_request(identification_data_t *data) { emm_sap_t emm_sap; int rc; struct emm_data_context_s *emm_ctx = NULL; LOG_FUNC_IN; /* * Notify EMM-AS SAP that Identity Request message has to be sent * to the UE */ MSC_LOG_TX_MESSAGE( MSC_NAS_EMM_MME, MSC_NAS_EMM_MME, NULL,0, "0 EMMAS_SECURITY_REQ ue id "NAS_UE_ID_FMT" ", data->ueid); emm_sap.primitive = EMMAS_SECURITY_REQ; emm_sap.u.emm_as.u.security.guti = NULL; emm_sap.u.emm_as.u.security.ueid = data->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_IDENT; emm_sap.u.emm_as.u.security.identType = data->type; #if defined(NAS_BUILT_IN_EPC) if (data->ueid > 0) { emm_ctx = emm_data_context_get(&_emm_data, data->ueid); } #else if (data->ueid < EMM_DATA_NB_UE_MAX) { emm_ctx = _emm_data.ctx[data->ueid]; } #endif /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, emm_ctx->security, FALSE, TRUE); rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { if (emm_ctx->T3470.id != NAS_TIMER_INACTIVE_ID) { /* Re-start T3470 timer */ emm_ctx->T3470.id = nas_timer_restart(emm_ctx->T3470.id); MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3470 restarted UE "NAS_UE_ID_FMT" ", data->ueid); } else { /* Start T3470 timer */ emm_ctx->T3470.id = nas_timer_start(emm_ctx->T3470.sec, _identification_t3470_handler, data); MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3470 started UE "NAS_UE_ID_FMT" ", data->ueid); } LOG_TRACE(INFO,"EMM-PROC - Timer T3470 (%d) expires in %ld seconds", emm_ctx->T3470.id, emm_ctx->T3470.sec); } LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _emm_detach_t3421_handler() ** ** ** ** Description: T3421 timeout handler ** ** ** ** 3GPP TS 24.301, section 5.5.2.2.4 case c ** ** On the first four expiries of the timer, the UE shall re- ** ** transmit the DETACH REQUEST message and shall reset and ** ** restart timer T3421. On the fifth expiry of timer T3421, ** ** the detach procedure shall be aborted. ** ** ** ** Inputs: args: handler parameters ** ** Others: _emm_detach_data ** ** ** ** Outputs: None ** ** Return: None ** ** Others: None ** ** ** ***************************************************************************/ void *_emm_detach_t3421_handler(void *args) { LOG_FUNC_IN; int rc; /* Increment the retransmission counter */ _emm_detach_data.count += 1; LOG_TRACE(WARNING, "EMM-PROC - T3421 timer expired, " "retransmission counter = %d", _emm_detach_data.count); if (_emm_detach_data.count < EMM_DETACH_COUNTER_MAX) { /* Retransmit the Detach Request message */ emm_sap_t emm_sap; emm_as_data_t *emm_as = &emm_sap.u.emm_as.u.data; /* Stop timer T3421 */ T3421.id = nas_timer_stop(T3421.id); /* Setup NAS information message to transfer */ emm_as->NASinfo = EMM_AS_NAS_INFO_DETACH; emm_as->NASmsg.length = 0; emm_as->NASmsg.value = NULL; /* Set the detach type */ emm_as->type = _emm_detach_data.type; /* Set the switch-off indicator */ emm_as->switch_off = _emm_detach_data.switch_off; /* Set the EPS mobile identity */ emm_as->guti = _emm_data.guti; emm_as->ueid = 0; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_as->sctx, _emm_data.security, FALSE, TRUE); /* * Notify EMM-AS SAP that Detach Request message has to * be sent to the network */ emm_sap.primitive = EMMAS_DATA_REQ; rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { /* Start T3421 timer */ T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, NULL); LOG_TRACE(INFO, "EMM-PROC - Timer T3421 (%d) expires in %ld " "seconds", T3421.id, T3421.sec); } } else { /* Abort the detach procedure */ rc = _emm_detach_abort(_emm_detach_data.type); } LOG_FUNC_RETURN(NULL); }
/**************************************************************************** ** ** ** Name: _identification_abort() ** ** ** ** Description: Aborts the identification procedure currently in progress ** ** ** ** Inputs: args: Identification data to be released ** ** Others: None ** ** ** ** Outputs: None ** ** Return: None ** ** Others: T3470 ** ** ** ***************************************************************************/ static int _identification_abort(void *args) { LOG_FUNC_IN; int rc = RETURNerror; identification_data_t *data = (identification_data_t *)(args); if (data) { unsigned int ueid = data->ueid; int notify_failure = data->notify_failure; struct emm_data_context_s *emm_ctx = NULL; /* Get the UE context */ #if defined(NAS_BUILT_IN_EPC) if (ueid > 0) { emm_ctx = emm_data_context_get(&_emm_data, ueid); } #else if (ueid < EMM_DATA_NB_UE_MAX) { emm_ctx = _emm_data.ctx[ueid]; } #endif LOG_TRACE(WARNING, "EMM-PROC - Abort identification procedure " "(ueid="NAS_UE_ID_FMT")", ueid); /* Stop timer T3470 */ if (emm_ctx->T3470.id != NAS_TIMER_INACTIVE_ID) { LOG_TRACE(INFO, "EMM-PROC - Stop timer T3470 (%d)", emm_ctx->T3470.id); emm_ctx->T3470.id = nas_timer_stop(emm_ctx->T3470.id); MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3470 stopped UE "NAS_UE_ID_FMT" ", data->ueid); } /* Release retransmission timer paramaters */ free(data); /* * Notify EMM that the identification procedure failed */ if (notify_failure) { MSC_LOG_TX_MESSAGE( MSC_NAS_EMM_MME, MSC_NAS_EMM_MME, NULL,0, "0 EMMREG_COMMON_PROC_REJ ue id "NAS_UE_ID_FMT" ", ueid); emm_sap_t emm_sap; emm_sap.primitive = EMMREG_COMMON_PROC_REJ; emm_sap.u.emm_reg.ueid = ueid; rc = emm_sap_send(&emm_sap); } else { rc = RETURNok; } } LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: lowerlayer_failure() ** ** ** ** Description: Notify the EPS Mobility Management entity that lower la- ** ** yers failed to deliver data to the network ** ** ** ** Inputs: ueid: UE lower layer identifier ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int lowerlayer_failure(unsigned int ueid) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; emm_sap.primitive = EMMREG_LOWERLAYER_FAILURE; emm_sap.u.emm_reg.ueid = ueid; rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: lowerlayer_success() ** ** ** ** Description: Notify the EPS Mobility Management entity that data have ** ** been successfully delivered to the network ** ** ** ** Inputs: ueid: UE lower layer identifier ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int lowerlayer_success(unsigned int ueid) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; emm_sap.primitive = EMMREG_LOWERLAYER_SUCCESS; emm_sap.u.emm_reg.ueid = ueid; rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: emm_proc_detach() ** ** ** ** Description: Initiates the detach procedure in order for the UE to de- ** ** tach for EPS services. ** ** ** ** 3GPP TS 24.301, section 5.5.2.2.1 ** ** In state EMM-REGISTERED or EMM-REGISTERED-INITIATED, the ** ** UE initiates the detach procedure by sending a DETACH RE- ** ** QUEST message to the network, starting timer T3421 and ** ** entering state EMM-DEREGISTERED-INITIATED. ** ** ** ** Inputs: type: Type of the requested detach ** ** switch_off: Indicates whether the detach is required ** ** because the UE is switched off or not ** ** Others: _emm_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: _emm_detach_data ** ** ** ***************************************************************************/ int emm_proc_detach(emm_proc_detach_type_t type, int switch_off) { LOG_FUNC_IN; emm_sap_t emm_sap; emm_as_data_t *emm_as = &emm_sap.u.emm_as.u.data; int rc; LOG_TRACE(INFO, "EMM-PROC - Initiate EPS detach type = %s (%d)", _emm_detach_type_str[type], type); /* Initialize the detach procedure internal data */ _emm_detach_data.count = 0; _emm_detach_data.switch_off = switch_off; _emm_detach_data.type = type; /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ rc = emm_proc_lowerlayer_initialize(emm_proc_detach_request, emm_proc_detach_failure, emm_proc_detach_release, NULL); if (rc != RETURNok) { LOG_TRACE(WARNING, "Failed to initialize EMM procedure handler"); LOG_FUNC_RETURN (RETURNerror); } /* Setup NAS information message to transfer */ emm_as->NASinfo = EMM_AS_NAS_INFO_DETACH; emm_as->NASmsg.length = 0; emm_as->NASmsg.value = NULL; /* Set the detach type */ emm_as->type = type; /* Set the switch-off indicator */ emm_as->switch_off = switch_off; /* Set the EPS mobile identity */ emm_as->guti = _emm_data.guti; emm_as->ueid = 0; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_as->sctx, _emm_data.security, FALSE, TRUE); /* * Notify EMM-AS SAP that Detach Request message has to * be sent to the network */ emm_sap.primitive = EMMAS_DATA_REQ; rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: emm_proc_attach_request() ** ** ** ** Description: Performs the attach procedure upon receipt of indication ** ** from lower layers that Attach Request message has been ** ** successfully delivered to the network. ** ** ** ** Inputs: args: Not used ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int emm_proc_attach_request(void *args) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; /* * Notify EMM that Attach Request has been sent to the network */ emm_sap.primitive = EMMREG_ATTACH_REQ; rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: lowerlayer_release() ** ** ** ** Description: Notify the EPS Mobility Management entity that NAS signal-** ** ling connection has been released ** ** ** ** Inputs: cause: Release cause ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int lowerlayer_release(int cause) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; /* Update the EPS Connection Management status */ _emm_data.ecm_status = ECM_IDLE; emm_sap.primitive = EMMREG_LOWERLAYER_RELEASE; emm_sap.u.emm_reg.ueid = 0; rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: emm_proc_attach_release() ** ** ** ** Description: Performs the attach procedure abnormal case upon receipt ** ** of NAS signalling connection release indication. ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.6, case b ** ** The attach procedure shall be aborted and the UE shall ** ** execute abnormal case attach procedure. ** ** ** ** Inputs: args: Not used ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int emm_proc_attach_release(void *args) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; LOG_TRACE(WARNING, "EMM-PROC - NAS signalling connection released"); /* Execute abnormal case attach procedure */ _emm_attach_abnormal_cases_bcd(&emm_sap); rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: _authentication_t3460_handler() ** ** ** ** Description: T3460 timeout handler ** ** Upon T3460 timer expiration, the authentication request ** ** message is retransmitted and the timer restarted. When ** ** retransmission counter is exceed, the MME shall abort the ** ** authentication procedure and any ongoing EMM specific ** ** procedure and release the NAS signalling connection. ** ** ** ** 3GPP TS 24.301, section 5.4.2.7, case b ** ** ** ** Inputs: args: handler parameters ** ** Others: None ** ** ** ** Outputs: None ** ** Return: None ** ** Others: None ** ** ** ***************************************************************************/ static void * _authentication_t3460_handler ( void *args) { LOG_FUNC_IN; int rc; authentication_data_t *data = (authentication_data_t *) (args); /* * Increment the retransmission counter */ data->retransmission_count += 1; LOG_TRACE (WARNING, "EMM-PROC - T3460 timer expired, retransmission " "counter = %d", data->retransmission_count); if (data->retransmission_count < AUTHENTICATION_COUNTER_MAX) { /* * Send authentication request message to the UE */ rc = _authentication_request (data); } else { unsigned int ueid = data->ueid; /* * Set the failure notification indicator */ data->notify_failure = TRUE; /* * Abort the authentication procedure */ rc = _authentication_abort (data); /* * Release the NAS signalling connection */ if (rc != RETURNerror) { emm_sap_t emm_sap; emm_sap.primitive = EMMAS_RELEASE_REQ; emm_sap.u.emm_as.u.release.guti = NULL; emm_sap.u.emm_as.u.release.ueid = ueid; emm_sap.u.emm_as.u.release.cause = EMM_AS_CAUSE_AUTHENTICATION; rc = emm_sap_send (&emm_sap); } } LOG_FUNC_RETURN (NULL); }
/**************************************************************************** ** ** ** Name: emm_proc_attach_restart() ** ** ** ** Description: Restarts the attach procedure ** ** ** ** Inputs: None ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int emm_proc_attach_restart(void) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; LOG_TRACE(INFO, "EMM-PROC - Restart EPS attach procedure"); /* * Notify EMM that the attach procedure has to be restarted */ emm_sap.primitive = EMMREG_ATTACH_INIT; emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency; rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: emm_proc_attach_set_detach() ** ** ** ** Description: Reset the network attachment indicator and enter state ** ** EMM-DEREGISTERED ** ** ** Inputs: None ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: _emm_data ** ** ** ***************************************************************************/ int emm_proc_attach_set_detach(void) { LOG_FUNC_IN; int rc; LOG_TRACE(WARNING, "EMM-PROC - UE is now locally detached from the network"); /* Reset the network attachment indicator */ _emm_data.is_attached = FALSE; /* * Notify that the UE is locally detached from the network */ emm_sap_t emm_sap; emm_sap.primitive = EMMREG_DETACH_CNF; rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: emm_proc_attach_complete() ** ** ** ** Description: Terminates the attach procedure when Attach Complete mes- ** ** sage has been successfully delivered to the MME. ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.4 ** ** Upon successfully sending the ATTACH COMPLETE message, ** ** the UE shall reset the attach attempt counter and tra- ** ** cking area updating attempt counter, enter state EMM- ** ** REGISTERED and set the EPS update status to EU1-UPDATED. ** ** ** ** Inputs: args: Not used ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: _emm_data, _emm_attach_data ** ** ** ***************************************************************************/ int emm_proc_attach_complete(void *args) { LOG_FUNC_IN; emm_sap_t emm_sap; esm_sap_t esm_sap; int rc; LOG_TRACE(INFO, "EMM-PROC - EPS attach complete"); /* Reset EMM procedure handler */ (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); /* Reset the attach attempt counter */ _emm_attach_data.attempt_count = 0; /* TODO: Reset the tracking area updating attempt counter */ /* Set the EPS update status to EU1 UPDATED */ _emm_data.status = EU1_UPDATED; _emm_data.is_attached = TRUE; /* * Notify EMM that network attach complete message has been delivered * to the network */ emm_sap.primitive = EMMREG_ATTACH_CNF; rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { /* * Notify ESM that the Activate Default EPS Bearer Context Accept * message has been delivered to the network within the Attach * Complete message */ esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_CNF; esm_sap.is_standalone = FALSE; rc = esm_sap_send(&esm_sap); } LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: _emm_attach_t3411_handler() ** ** ** ** Description: T3411 timeout handler ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.6 ** ** Upon T3411 timer expiration, the attach procedure shall ** ** be restarted, if still required by ESM sublayer. ** ** ** ** Inputs: args: handler parameters ** ** Others: None ** ** ** ** Outputs: None ** ** Return: None ** ** Others: T3411 ** ** ** ***************************************************************************/ static void *_emm_attach_t3411_handler(void *args) { LOG_FUNC_IN; emm_sap_t emm_sap; LOG_TRACE(WARNING, "EMM-PROC - T3411 timer expired"); /* Stop T3411 timer */ T3411.id = nas_timer_stop(T3411.id); /* * Notify EMM that timer T3411 expired and attach procedure has to be * restarted */ emm_sap.primitive = EMMREG_ATTACH_INIT; emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency; (void) emm_sap_send(&emm_sap); LOG_FUNC_RETURN(NULL); }
/**************************************************************************** ** ** ** Name: esm_proc_pdn_disconnect_request() ** ** ** ** Description: Initiates PDN disconnection procedure in order to request ** ** disconnection from a PDN. ** ** ** ** 3GPP TS 24.301, section 6.5.2.2 ** ** The UE requests PDN disconnection from a PDN by sending a ** ** PDN DISCONNECT REQUEST message to the MME, starting timer ** ** T3492 and entering state PROCEDURE TRANSACTION PENDING. ** ** ** ** Inputs: is_standalone: Should be always TRUE ** ** pti: Procedure transaction identity ** ** msg: Encoded PDN disconnect request message to ** ** be sent ** ** sent_by_ue: Not used ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int esm_proc_pdn_disconnect_request(int is_standalone, int pti, OctetString *msg, int sent_by_ue) { LOG_FUNC_IN; int rc = RETURNok; LOG_TRACE(INFO, "ESM-PROC - Initiate PDN disconnection (pti=%d)", pti); if (is_standalone) { emm_sap_t emm_sap; emm_esm_data_t *emm_esm = &emm_sap.u.emm_esm.u.data; /* * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { /* Start T3482 retransmission timer */ rc = esm_pt_start_timer(pti, msg, T3492_DEFAULT_VALUE, _pdn_disconnect_t3492_handler); } } if (rc != RETURNerror) { /* Set the procedure transaction state to PENDING */ rc = esm_pt_set_status(pti, ESM_PT_PENDING); if (rc != RETURNok) { /* The procedure transaction was already in PENDING state */ LOG_TRACE(WARNING, "ESM-PROC - PTI %d was already PENDING", pti); } } LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: emm_proc_detach_request() ** ** ** ** Description: Performs the detach procedure upon receipt of indication ** ** from lower layers that Detach Request message has been ** ** successfully delivered to the network. ** ** ** ** Inputs: args: Not used ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: T3421 ** ** ** ***************************************************************************/ int emm_proc_detach_request(void *args) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; if ( !_emm_detach_data.switch_off ) { /* Start T3421 timer */ T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, NULL); LOG_TRACE(INFO, "EMM-PROC - Timer T3421 (%d) expires in %ld seconds", T3421.id, T3421.sec); } /* * Notify EMM that Detach Request has been sent to the network */ emm_sap.primitive = EMMREG_DETACH_REQ; rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: esm_proc_eps_bearer_context_deactivate_accept() ** ** ** ** Description: Performs EPS bearer context deactivation procedure accep- ** ** ted by the UE. ** ** ** ** 3GPP TS 24.301, section 6.4.4.3 ** ** The UE accepts EPS bearer context deactivation by sending ** ** DEACTIVATE EPS BEARER CONTEXT ACCEPT message and entering ** ** the state BEARER CONTEXT INACTIVE. ** ** ** ** Inputs: is_standalone: Should be always TRUE ** ** ebi: EPS bearer identity ** ** msg: Encoded ESM message to be sent ** ** ue_triggered: TRUE if the EPS bearer context procedure ** ** was triggered by the UE ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; int rc = RETURNok; LOG_TRACE(INFO,"ESM-PROC - EPS bearer context deactivation accepted"); if (is_standalone) { emm_sap_t emm_sap; /* * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; emm_sap.u.emm_esm.ueid = 0; emm_sap.u.emm_esm.u.data.msg.length = msg->length; emm_sap.u.emm_esm.u.data.msg.value = msg->value; rc = emm_sap_send(&emm_sap); } if (rc != RETURNerror) { /* Set the EPS bearer context state to INACTIVE */ rc = esm_ebr_set_status(ebi, ESM_EBR_INACTIVE, ue_triggered); if (rc != RETURNok) { /* The EPS bearer context was already in INACTIVE state */ LOG_TRACE(WARNING, "ESM-PROC - EBI %d was already INACTIVE", ebi); /* Accept network retransmission of already accepted deactivate * EPS bearer context request */ LOG_FUNC_RETURN (RETURNok); } /* Release EPS bearer data */ rc = esm_ebr_release(ebi); } LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _identification_abort() ** ** ** ** Description: Aborts the identification procedure currently in progress ** ** ** ** Inputs: args: Identification data to be released ** ** Others: None ** ** ** ** Outputs: None ** ** Return: None ** ** Others: T3470 ** ** ** ***************************************************************************/ static int _identification_abort(void *args) { LOG_FUNC_IN; int rc = RETURNerror; identification_data_t *data = (identification_data_t *)(args); if (data) { unsigned int ueid = data->ueid; int notify_failure = data->notify_failure; LOG_TRACE(WARNING, "EMM-PROC - Abort identification procedure " "(ueid=%u)", ueid); /* Stop timer T3470 */ if (T3470.id != NAS_TIMER_INACTIVE_ID) { LOG_TRACE(INFO, "EMM-PROC - Stop timer T3470 (%d)", T3470.id); T3470.id = nas_timer_stop(T3470.id); } /* Release retransmission timer paramaters */ free(data); /* * Notify EMM that the identification procedure failed */ if (notify_failure) { emm_sap_t emm_sap; emm_sap.primitive = EMMREG_COMMON_PROC_REJ; emm_sap.u.emm_reg.ueid = ueid; rc = emm_sap_send(&emm_sap); } else { rc = RETURNok; } } LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: _emm_attach_t3410_handler() ** ** ** ** Description: T3410 timeout handler ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.6, case c ** ** Upon T3410 timer expiration, the attach procedure shall ** ** be aborted and the UE shall execute abnormal case attach ** ** procedure. ** ** The NAS signalling connection shall be released locally. ** ** ** ** Inputs: args: handler parameters ** ** Others: None ** ** ** ** Outputs: None ** ** Return: None ** ** Others: T3410 ** ** ** ***************************************************************************/ void *_emm_attach_t3410_handler(void *args) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; LOG_TRACE(WARNING, "EMM-PROC - T3410 timer expired"); /* Stop T3410 timer */ T3410.id = nas_timer_stop(T3410.id); /* Execute abnormal case attach procedure */ _emm_attach_abnormal_cases_bcd(&emm_sap); rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { /* Locally release the NAS signalling connection */ _emm_data.ecm_status = ECM_IDLE; } LOG_FUNC_RETURN(NULL); }
/**************************************************************************** ** ** ** Name: lowerlayer_data_req() ** ** ** ** Description: Notify the EPS Mobility Management entity that data have ** ** to be transfered to lower layers ** ** ** ** Inputs: ueid: UE lower layer identifier ** ** data: Data to be transfered to lower layers ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int lowerlayer_data_req(unsigned int ueid, const OctetString *data) { LOG_FUNC_IN; int rc; emm_sap_t emm_sap; emm_security_context_t *sctx = NULL; struct emm_data_context_s *ctx = NULL; emm_sap.primitive = EMMAS_DATA_REQ; emm_sap.u.emm_as.u.data.guti = _emm_data.guti; emm_sap.u.emm_as.u.data.ueid = 0; sctx = _emm_data.security; emm_sap.u.emm_as.u.data.NASinfo = 0; emm_sap.u.emm_as.u.data.NASmsg.length = data->length; emm_sap.u.emm_as.u.data.NASmsg.value = data->value; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, sctx, FALSE, TRUE); rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: esm_proc_status() ** ** ** ** Description: Initiates ESM status procedure. ** ** ** ** Inputs: is_standalone: Not used - Always TRUE ** ** ueid: UE lower layer identifier ** ** ebi: Not used ** ** msg: Encoded ESM status message to be sent ** ** ue_triggered: Not used ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int esm_proc_status ( int is_standalone, emm_data_context_t * ctx, int ebi, OctetString * msg, int ue_triggered) { LOG_FUNC_IN; int rc; emm_sap_t emm_sap; LOG_TRACE (INFO, "ESM-PROC - ESM status procedure requested"); /* * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; emm_sap.u.emm_esm.ueid = ctx->ueid; emm_sap.u.emm_esm.ctx = ctx; emm_sap.u.emm_esm.u.data.msg.length = msg->length; emm_sap.u.emm_esm.u.data.msg.value = msg->value; rc = emm_sap_send (&emm_sap); LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: emm_proc_detach_failure() ** ** ** ** Description: Performs the detach procedure abnormal case upon receipt ** ** of transmission failure of Detach Request message. ** ** ** ** 3GPP TS 24.301, section 5.5.2.2.4, case h ** ** The UE shall restart the detach procedure. ** ** ** ** Inputs: is_initial: Not used ** ** args: Not used ** ** Others: _emm_detach_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int emm_proc_detach_failure(int is_initial, void *args) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; LOG_TRACE(WARNING, "EMM-PROC - Network detach failure"); /* Reset EMM procedure handler */ (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); /* Stop timer T3421 */ T3421.id = nas_timer_stop(T3421.id); /* * Notify EMM that detach procedure has to be restarted */ emm_sap.primitive = EMMREG_DETACH_INIT; emm_sap.u.emm_reg.u.detach.switch_off = _emm_detach_data.switch_off; rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: esm_proc_dedicated_eps_bearer_context_accept() ** ** ** ** Description: Performs dedicated EPS bearer context activation proce- ** ** dure accepted by the UE. ** ** ** ** 3GPP TS 24.301, section 6.4.2.3 ** ** The UE accepts dedicated EPS bearer context activation by ** ** sending ACTIVATE DEDICATED EPS BEARER CONTEXT ACCEPT mes- ** ** sage and entering the state BEARER CONTEXT ACTIVE. ** ** ** ** Inputs: is_standalone: Not used ** ** ebi: EPS bearer identity ** ** msg: Encoded ESM message to be sent ** ** ue_triggered: TRUE if the EPS bearer context procedure ** ** was triggered by the UE ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int esm_proc_dedicated_eps_bearer_context_accept(int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; int rc; LOG_TRACE(INFO,"ESM-PROC - Dedicated EPS bearer context activation " "accepted by the UE (ebi=%d)", ebi); emm_sap_t emm_sap; emm_esm_data_t *emm_esm = &emm_sap.u.emm_esm.u.data; /* * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { /* Set the EPS bearer context state to ACTIVE */ rc = esm_ebr_set_status(ebi, ESM_EBR_ACTIVE, ue_triggered); if (rc != RETURNok) { /* The EPS bearer context was already in ACTIVE state */ LOG_TRACE(WARNING, "ESM-PROC - EBI %d was already ACTIVE", ebi); /* Accept network retransmission of already accepted activate * dedicated EPS bearer context request */ LOG_FUNC_RETURN (RETURNok); } } LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _emm_detach_abort() ** ** ** ** Description: Aborts the detach procedure ** ** ** ** Inputs: type: not used ** ** Others: _emm_detach_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: T3421 ** ** ** ***************************************************************************/ static int _emm_detach_abort(emm_proc_detach_type_t type) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc ; LOG_TRACE(WARNING, "EMM-PROC - Abort the detach procedure"); /* Reset EMM procedure handler */ (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); /* Stop timer T3421 */ T3421.id = nas_timer_stop(T3421.id); /* * Notify EMM that detach procedure failed */ emm_sap.primitive = EMMREG_DETACH_FAILED; emm_sap.u.emm_reg.u.detach.type = type; rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN (rc); }