diff --git a/openair-cn/NAS/EURECOM-NAS/src/UEprocess.c b/openair-cn/NAS/EURECOM-NAS/src/UEprocess.c index a042c66d97655b6d5fd209f0b99ab30e95918a86..c9f0f4b0a653491db41e01de48beb6c43736c4b4 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/UEprocess.c +++ b/openair-cn/NAS/EURECOM-NAS/src/UEprocess.c @@ -200,6 +200,7 @@ static void* _nas_user_mngr(void* args) int exit_loop = FALSE; int nb_command; int bytes; + int i; int *fd = (int*) args; @@ -227,7 +228,7 @@ static void* _nas_user_mngr(void* args) /* Decode the user data message */ nb_command = user_api_decode_data (bytes); - for (int i = 0; i < nb_command; i++) + for (i = 0; i < nb_command; i++) { /* Get the user data to be processed */ const void* data = user_api_get_data (i); diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c b/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c index 23c8ba5741d54ec8e2b5b63fd9f7ca79a8da37f3..95f8c23f3d5661032b5ab168772345d2b5487695 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c @@ -1,36 +1,36 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source Attach.c +Source Attach.c -Version 0.1 +Version 0.1 -Date 2012/12/04 +Date 2012/12/04 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines the attach related EMM procedure executed by the - Non-Access Stratum. +Description Defines the attach related EMM procedure executed by the + Non-Access Stratum. - To get internet connectivity from the network, the network - have to know about the UE. When the UE is switched on, it - has to initiate the attach procedure to get initial access - to the network and register its presence to the Evolved - Packet Core (EPC) network in order to receive EPS services. + To get internet connectivity from the network, the network + have to know about the UE. When the UE is switched on, it + has to initiate the attach procedure to get initial access + to the network and register its presence to the Evolved + Packet Core (EPC) network in order to receive EPS services. - As a result of a successful attach procedure, a context is - created for the UE in the MME, and a default bearer is esta- - blished between the UE and the PDN-GW. The UE gets the home - agent IPv4 and IPv6 addresses and full connectivity to the - IP network. + As a result of a successful attach procedure, a context is + created for the UE in the MME, and a default bearer is esta- + blished between the UE and the PDN-GW. The UE gets the home + agent IPv4 and IPv6 addresses and full connectivity to the + IP network. - The network may also initiate the activation of additional - dedicated bearers for the support of a specific service. + The network may also initiate the activation of additional + dedicated bearers for the support of a specific service. *****************************************************************************/ @@ -49,8 +49,8 @@ Description Defines the attach related EMM procedure executed by the #include "mme_api.h" #endif -#include <string.h> // memcmp, memcpy -#include <stdlib.h> // malloc, free +#include <string.h> // memcmp, memcpy +#include <stdlib.h> // malloc, free /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -61,84 +61,84 @@ Description Defines the attach related EMM procedure executed by the /****************************************************************************/ /* String representation of the EPS attach type */ -static const char* _emm_attach_type_str[] = { +static const char *_emm_attach_type_str[] = { "EPS", "IMSI", "EMERGENCY", "RESERVED" }; /* * -------------------------------------------------------------------------- - * Internal data handled by the attach procedure in the UE + * Internal data handled by the attach procedure in the UE * -------------------------------------------------------------------------- */ #ifdef NAS_UE /* * Timer handlers */ -void* _emm_attach_t3410_handler(void*); -static void* _emm_attach_t3411_handler(void*); -static void* _emm_attach_t3402_handler(void*); +void *_emm_attach_t3410_handler(void *); +static void *_emm_attach_t3411_handler(void *); +static void *_emm_attach_t3402_handler(void *); /* * Abnormal case attach procedure */ -static void _emm_attach_abnormal_cases_bcd(emm_sap_t*); +static void _emm_attach_abnormal_cases_bcd(emm_sap_t *); /* * Internal data used for attach procedure */ static struct { -#define EMM_ATTACH_COUNTER_MAX 5 - unsigned int attempt_count; /* Counter used to limit the number of - * subsequently rejected attach attempts */ +#define EMM_ATTACH_COUNTER_MAX 5 + unsigned int attempt_count; /* Counter used to limit the number of + * subsequently rejected attach attempts */ } _emm_attach_data = {0}; #endif // NAS_UE /* * -------------------------------------------------------------------------- - * Internal data handled by the attach procedure in the MME + * Internal data handled by the attach procedure in the MME * -------------------------------------------------------------------------- */ #ifdef NAS_MME /* * Timer handlers */ -static void* _emm_attach_t3450_handler(void*); +static void *_emm_attach_t3450_handler(void *); /* * Functions that may initiate EMM common procedures */ -static int _emm_attach_identify(void*); -static int _emm_attach_security(void*); -static int _emm_attach(void*); +static int _emm_attach_identify(void *); +static int _emm_attach_security(void *); +static int _emm_attach(void *); /* * Abnormal case attach procedures */ -static int _emm_attach_release(void*); -static int _emm_attach_reject(void*); -static int _emm_attach_abort(void*); - -static int _emm_attach_have_changed(const emm_data_context_t* ctx, - emm_proc_attach_type_t type, int ksi, - GUTI_t* guti, imsi_t* imsi, imei_t* imei, - int eea, int eia); -static int _emm_attach_update(emm_data_context_t* ctx, unsigned int ueid, - emm_proc_attach_type_t type, int ksi, - GUTI_t* guti, imsi_t* imsi, imei_t* imei, - int eea, int eia, const OctetString* esm_msg); +static int _emm_attach_release(void *); +static int _emm_attach_reject(void *); +static int _emm_attach_abort(void *); + +static int _emm_attach_have_changed(const emm_data_context_t *ctx, + emm_proc_attach_type_t type, int ksi, + GUTI_t *guti, imsi_t *imsi, imei_t *imei, + int eea, int eia); +static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, + emm_proc_attach_type_t type, int ksi, + GUTI_t *guti, imsi_t *imsi, imei_t *imei, + int eea, int eia, const OctetString *esm_msg); /* * Internal data used for attach procedure */ typedef struct { - unsigned int ueid; /* UE identifier */ -#define ATTACH_COUNTER_MAX 5 - unsigned int retransmission_count; /* Retransmission counter */ - OctetString esm_msg; /* ESM message to be sent within - * the Attach Accept message */ + unsigned int ueid; /* UE identifier */ +#define ATTACH_COUNTER_MAX 5 + unsigned int retransmission_count; /* Retransmission counter */ + OctetString esm_msg; /* ESM message to be sent within + * the Attach Accept message */ } attach_data_t; -static int _emm_attach_accept(emm_data_context_t* emm_ctx, attach_data_t* data); +static int _emm_attach_accept(emm_data_context_t *emm_ctx, attach_data_t *data); #endif // NAS_MME @@ -148,30 +148,30 @@ static int _emm_attach_accept(emm_data_context_t* emm_ctx, attach_data_t* data); /* * -------------------------------------------------------------------------- - * Attach procedure executed by the UE + * Attach procedure executed by the UE * -------------------------------------------------------------------------- */ #ifdef NAS_UE /**************************************************************************** ** ** - ** Name: emm_proc_attach() ** + ** Name: emm_proc_attach() ** ** ** ** Description: Initiate EPS attach procedure to register a UE in PS mode ** - ** of operation for EPS services only, or register a UE for ** - ** emergency bearer services. ** + ** of operation for EPS services only, or register a UE for ** + ** emergency bearer services. ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.2 ** - ** In state EMM-DEREGISTERED, the UE initiates the attach ** - ** procedure by sending an ATTACH REQUEST message to the MME,** - ** starting timer T3410 and entering state EMM-REGISTERED- ** - ** INITIATED. ** + ** In state EMM-DEREGISTERED, the UE initiates the attach ** + ** procedure by sending an ATTACH REQUEST message to the MME,** + ** starting timer T3410 and entering state EMM-REGISTERED- ** + ** INITIATED. ** ** ** - ** Inputs: type: Type of the requested attach ** - ** Others: _emm_data ** + ** Inputs: type: Type of the requested attach ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3402, T3410, T3411 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3402, T3410, T3411 ** ** ** ***************************************************************************/ int emm_proc_attach(emm_proc_attach_type_t type) @@ -184,11 +184,11 @@ int emm_proc_attach(emm_proc_attach_type_t type) int rc; LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach type = %s (%d)", - _emm_attach_type_str[type], type); + _emm_attach_type_str[type], type); /* Update the emergency bearer service indicator */ if (type == EMM_ATTACH_TYPE_EMERGENCY) { - _emm_data.is_emergency = TRUE; + _emm_data.is_emergency = TRUE; } /* Setup initial NAS information message to transfer */ @@ -197,11 +197,11 @@ int emm_proc_attach(emm_proc_attach_type_t type) emm_as->type = type; /* Set the RRC connection establishment cause */ if (_emm_data.is_emergency) { - emm_as->RRCcause = NET_ESTABLISH_CAUSE_EMERGENCY; - emm_as->RRCtype = NET_ESTABLISH_TYPE_EMERGENCY_CALLS; + emm_as->RRCcause = NET_ESTABLISH_CAUSE_EMERGENCY; + emm_as->RRCtype = NET_ESTABLISH_TYPE_EMERGENCY_CALLS; } else { - emm_as->RRCcause = NET_ESTABLISH_CAUSE_MO_SIGNAL; - emm_as->RRCtype = NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL; + emm_as->RRCcause = NET_ESTABLISH_CAUSE_MO_SIGNAL; + emm_as->RRCtype = NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL; } /* Set the PLMN identifier of the selected PLMN */ emm_as->plmnID = &_emm_data.splmn; @@ -214,42 +214,39 @@ int emm_proc_attach(emm_proc_attach_type_t type) emm_as->UEid.imei = NULL; /* Check whether the UE is configured for "AttachWithIMSI" */ if (_emm_data.AttachWithImsi) { - /* Check whether the selected PLMN is neither the registered PLMN - * nor in the list of equivalent PLMNs */ - if ( (!_emm_data.is_rplmn) && (!_emm_data.is_eplmn) ) { - /* Include the IMSI */ - emm_as->UEid.imsi = _emm_data.imsi; - } - } - else if (_emm_data.guti) { - /* Include a valid GUTI and the last visited registered TAI */ - emm_as->UEid.guti = _emm_data.guti; - emm_as->UEid.tai = _emm_data.tai; - } - else if (!_emm_data.is_emergency) { - /* Include the IMSI if no valid GUTI is available */ - emm_as->UEid.imsi = _emm_data.imsi; - } - else { - /* The UE is attaching for emergency bearer services and - * does not hold a valid GUTI */ - if (_emm_data.imsi) { - /* Include the IMSI if valid (USIM is present) */ - emm_as->UEid.imsi = _emm_data.imsi; - } else { - /* Include the IMEI if the IMSI is not valid */ - emm_as->UEid.imei = _emm_data.imei; - } + /* Check whether the selected PLMN is neither the registered PLMN + * nor in the list of equivalent PLMNs */ + if ( (!_emm_data.is_rplmn) && (!_emm_data.is_eplmn) ) { + /* Include the IMSI */ + emm_as->UEid.imsi = _emm_data.imsi; + } + } else if (_emm_data.guti) { + /* Include a valid GUTI and the last visited registered TAI */ + emm_as->UEid.guti = _emm_data.guti; + emm_as->UEid.tai = _emm_data.tai; + } else if (!_emm_data.is_emergency) { + /* Include the IMSI if no valid GUTI is available */ + emm_as->UEid.imsi = _emm_data.imsi; + } else { + /* The UE is attaching for emergency bearer services and + * does not hold a valid GUTI */ + if (_emm_data.imsi) { + /* Include the IMSI if valid (USIM is present) */ + emm_as->UEid.imsi = _emm_data.imsi; + } else { + /* Include the IMEI if the IMSI is not valid */ + emm_as->UEid.imei = _emm_data.imei; + } } /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_as->sctx, _emm_data.security, FALSE, FALSE); emm_as->ksi = EMM_AS_NO_KEY_AVAILABLE; if (_emm_data.security) { - if (_emm_data.security->type != EMM_KSI_NOT_AVAILABLE) { - emm_as->ksi = _emm_data.security->eksi; - } - emm_as->encryption = _emm_data.security->capability.encryption; - emm_as->integrity = _emm_data.security->capability.integrity; + if (_emm_data.security->type != EMM_KSI_NOT_AVAILABLE) { + emm_as->ksi = _emm_data.security->eksi; + } + emm_as->encryption = _emm_data.security->capability.encryption; + emm_as->integrity = _emm_data.security->capability.integrity; } /* * Notify ESM that initiation of a PDN connectivity procedure @@ -266,34 +263,34 @@ int emm_proc_attach(emm_proc_attach_type_t type) rc = esm_sap_send(&esm_sap); if (rc != RETURNerror) { - /* Setup EMM procedure handler to be executed upon receiving - * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(emm_proc_attach_request, - emm_proc_attach_failure, - emm_proc_attach_release, NULL); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "Failed to initialize EMM procedure handler"); - LOG_FUNC_RETURN (RETURNerror); - } - - /* Start T3410 timer */ - T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, NULL); - LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in %ld seconds", - T3410.id, T3410.sec); - /* Stop T3402 and T3411 timers if running */ - T3402.id = nas_timer_stop(T3402.id); - T3411.id = nas_timer_stop(T3411.id); - - /* - * Notify EMM-AS SAP that a RRC connection establishment procedure - * is requested from the Access-Stratum to send initial NAS message - * attach request to the network - */ - emm_sap.primitive = EMMAS_ESTABLISH_REQ; - /* Get the PDN connectivity request to transfer within the ESM - * container of the initial attach request message */ - emm_sap.u.emm_as.u.establish.NASmsg = esm_sap.send; - rc = emm_sap_send(&emm_sap); + /* Setup EMM procedure handler to be executed upon receiving + * lower layer notification */ + rc = emm_proc_lowerlayer_initialize(emm_proc_attach_request, + emm_proc_attach_failure, + emm_proc_attach_release, NULL); + if (rc != RETURNok) { + LOG_TRACE(WARNING, "Failed to initialize EMM procedure handler"); + LOG_FUNC_RETURN (RETURNerror); + } + + /* Start T3410 timer */ + T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, NULL); + LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in %ld seconds", + T3410.id, T3410.sec); + /* Stop T3402 and T3411 timers if running */ + T3402.id = nas_timer_stop(T3402.id); + T3411.id = nas_timer_stop(T3411.id); + + /* + * Notify EMM-AS SAP that a RRC connection establishment procedure + * is requested from the Access-Stratum to send initial NAS message + * attach request to the network + */ + emm_sap.primitive = EMMAS_ESTABLISH_REQ; + /* Get the PDN connectivity request to transfer within the ESM + * container of the initial attach request message */ + emm_sap.u.emm_as.u.establish.NASmsg = esm_sap.send; + rc = emm_sap_send(&emm_sap); } LOG_FUNC_RETURN(rc); @@ -301,21 +298,21 @@ int emm_proc_attach(emm_proc_attach_type_t type) /**************************************************************************** ** ** - ** Name: emm_proc_attach_request() ** + ** 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. ** + ** from lower layers that Attach Request message has been ** + ** successfully delivered to the network. ** ** ** - ** Inputs: args: Not used ** - ** Others: None ** + ** Inputs: args: Not used ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_attach_request(void* args) +int emm_proc_attach_request(void *args) { LOG_FUNC_IN; @@ -333,39 +330,39 @@ int emm_proc_attach_request(void* args) /**************************************************************************** ** ** - ** Name: emm_proc_attach_accept() ** + ** Name: emm_proc_attach_accept() ** ** ** ** Description: Performs the attach procedure accepted by the network. ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.4 ** - ** Upon receiving the ATTACH ACCEPT message, the UE shall ** - ** stop timer T3410 and send an ATTACH COMPLETE message to ** - ** the MME. ** - ** ** - ** Inputs: t3412: Value of the T3412 timer in seconds ** - ** t3402: Value of the T3402 timer in seconds ** - ** t3423: Value of the T3423 timer in seconds ** - ** n_tais: Number of tracking area identities contai- ** - ** ned in the TAI list ** - ** tai: The TAI list that identifies the tracking ** - ** areas the UE is registered to ** - ** guti: New UE's temporary identity assigned by ** - ** the MME (GUTI reallocation) ** - ** n_eplmns: Number of equivalent PLMNs ** - ** eplmns: List of equivalent PLMNs ** - ** esm_msg: Activate default EPS bearer context re- ** - ** quest ESM message ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, T3412, T3402, T3423 ** + ** Upon receiving the ATTACH ACCEPT message, the UE shall ** + ** stop timer T3410 and send an ATTACH COMPLETE message to ** + ** the MME. ** + ** ** + ** Inputs: t3412: Value of the T3412 timer in seconds ** + ** t3402: Value of the T3402 timer in seconds ** + ** t3423: Value of the T3423 timer in seconds ** + ** n_tais: Number of tracking area identities contai- ** + ** ned in the TAI list ** + ** tai: The TAI list that identifies the tracking ** + ** areas the UE is registered to ** + ** guti: New UE's temporary identity assigned by ** + ** the MME (GUTI reallocation) ** + ** n_eplmns: Number of equivalent PLMNs ** + ** eplmns: List of equivalent PLMNs ** + ** esm_msg: Activate default EPS bearer context re- ** + ** quest ESM message ** + ** Others: None ** + ** ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data, T3412, T3402, T3423 ** ** ** ***************************************************************************/ int emm_proc_attach_accept(long t3412, long t3402, long t3423, - int n_tais, tai_t* tai, GUTI_t* guti, - int n_eplmns, plmn_t* eplmn, - const OctetString* esm_msg) + int n_tais, tai_t *tai, GUTI_t *guti, + int n_eplmns, plmn_t *eplmn, + const OctetString *esm_msg) { LOG_FUNC_IN; @@ -382,51 +379,51 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, /* Delete old TAI list and store the received TAI list */ _emm_data.ltai.n_tais = n_tais; for (int i = 0; (i < n_tais) && (i < EMM_DATA_TAI_MAX); i++) { - _emm_data.ltai.tai[i] = tai[i]; + _emm_data.ltai.tai[i] = tai[i]; } /* Update periodic tracking area update timer value */ T3412.sec = t3412; /* Update attach failure timer value */ if ( !(t3402 < 0) ) { - T3402.sec = t3402; + T3402.sec = t3402; } /* Update E-UTRAN deactivate ISR timer value */ if ( !(t3423 < 0) ) { - T3423.sec = t3423; + T3423.sec = t3423; } /* Delete old GUTI and store the new assigned GUTI if provided */ if (guti) { - *_emm_data.guti = *guti; + *_emm_data.guti = *guti; } /* Update the stored list of equivalent PLMNs */ _emm_data.nvdata.eplmn.n_plmns = 0; if (n_eplmns > 0) { - for (int i = 0; (i < n_eplmns) && (i < EMM_DATA_EPLMN_MAX); i++) { - int is_forbidden = FALSE; - if (!_emm_data.is_emergency) { - /* If the attach procedure is not for emergency bearer - * services, the UE shall remove from the list any PLMN - * code that is already in the list of forbidden PLMNs */ - for (int j = 0; j < _emm_data.fplmn.n_plmns; j++) { - if (PLMNS_ARE_EQUAL(eplmn[i], _emm_data.fplmn.plmn[j])) { - is_forbidden = TRUE; - break; - } - } - } - if ( !is_forbidden ) { - _emm_data.nvdata.eplmn.plmn[_emm_data.nvdata.eplmn.n_plmns++] = - eplmn[i]; - } - } - /* Add the PLMN code of the registered PLMN that sent the list */ - if (_emm_data.nvdata.eplmn.n_plmns < EMM_DATA_EPLMN_MAX) { - _emm_data.nvdata.eplmn.plmn[_emm_data.nvdata.eplmn.n_plmns++] = - _emm_data.splmn; - } + for (int i = 0; (i < n_eplmns) && (i < EMM_DATA_EPLMN_MAX); i++) { + int is_forbidden = FALSE; + if (!_emm_data.is_emergency) { + /* If the attach procedure is not for emergency bearer + * services, the UE shall remove from the list any PLMN + * code that is already in the list of forbidden PLMNs */ + for (int j = 0; j < _emm_data.fplmn.n_plmns; j++) { + if (PLMNS_ARE_EQUAL(eplmn[i], _emm_data.fplmn.plmn[j])) { + is_forbidden = TRUE; + break; + } + } + } + if ( !is_forbidden ) { + _emm_data.nvdata.eplmn.plmn[_emm_data.nvdata.eplmn.n_plmns++] = + eplmn[i]; + } + } + /* Add the PLMN code of the registered PLMN that sent the list */ + if (_emm_data.nvdata.eplmn.n_plmns < EMM_DATA_EPLMN_MAX) { + _emm_data.nvdata.eplmn.plmn[_emm_data.nvdata.eplmn.n_plmns++] = + _emm_data.splmn; + } } /* @@ -437,52 +434,49 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, esm_sap.recv = esm_msg; rc = esm_sap_send(&esm_sap); - if ( (rc != RETURNerror) && (esm_sap.err == ESM_SAP_SUCCESS) ) - { - /* Setup EMM procedure handler to be executed upon receiving - * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(emm_proc_attach_complete, - emm_proc_attach_failure, - NULL, NULL); - if (rc != RETURNok) { - LOG_TRACE(WARNING, - "EMM-PROC - Failed to initialize EMM procedure handler"); - LOG_FUNC_RETURN (RETURNerror); - } - /* - * Notify EMM-AS SAP that Attach Complete message together with - * an Activate Default EPS Bearer Context Accept message has to - * be sent to the network - */ - 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; - /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, - _emm_data.security, FALSE, TRUE); - /* Get the activate default EPS bearer context accept message - * to be transfered within the ESM container of the attach - * complete message */ - emm_sap.u.emm_as.u.data.NASinfo = EMM_AS_NAS_DATA_ATTACH; - emm_sap.u.emm_as.u.data.NASmsg = esm_sap.send; - rc = emm_sap_send(&emm_sap); - } - else if (esm_sap.err != ESM_SAP_DISCARDED) { - /* 3GPP TS 24.301, section 5.5.1.2.6, case j - * If the ACTIVATE DEFAULT BEARER CONTEXT REQUEST message combined - * with the ATTACH ACCEPT is not accepted by the UE due to failure - * in the UE ESM sublayer, then the UE shall initiate the detach - * procedure by sending a DETACH REQUEST message to the network. - */ - emm_sap.primitive = EMMREG_DETACH_INIT; - rc = emm_sap_send(&emm_sap); - } - else { - /* - * ESM procedure failed and, received message has been discarded or - * Status message has been returned; ignore ESM procedure failure - */ - rc = RETURNok; + if ( (rc != RETURNerror) && (esm_sap.err == ESM_SAP_SUCCESS) ) { + /* Setup EMM procedure handler to be executed upon receiving + * lower layer notification */ + rc = emm_proc_lowerlayer_initialize(emm_proc_attach_complete, + emm_proc_attach_failure, + NULL, NULL); + if (rc != RETURNok) { + LOG_TRACE(WARNING, + "EMM-PROC - Failed to initialize EMM procedure handler"); + LOG_FUNC_RETURN (RETURNerror); + } + /* + * Notify EMM-AS SAP that Attach Complete message together with + * an Activate Default EPS Bearer Context Accept message has to + * be sent to the network + */ + 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; + /* Setup EPS NAS security data */ + emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, + _emm_data.security, FALSE, TRUE); + /* Get the activate default EPS bearer context accept message + * to be transfered within the ESM container of the attach + * complete message */ + emm_sap.u.emm_as.u.data.NASinfo = EMM_AS_NAS_DATA_ATTACH; + emm_sap.u.emm_as.u.data.NASmsg = esm_sap.send; + rc = emm_sap_send(&emm_sap); + } else if (esm_sap.err != ESM_SAP_DISCARDED) { + /* 3GPP TS 24.301, section 5.5.1.2.6, case j + * If the ACTIVATE DEFAULT BEARER CONTEXT REQUEST message combined + * with the ATTACH ACCEPT is not accepted by the UE due to failure + * in the UE ESM sublayer, then the UE shall initiate the detach + * procedure by sending a DETACH REQUEST message to the network. + */ + emm_sap.primitive = EMMREG_DETACH_INIT; + rc = emm_sap_send(&emm_sap); + } else { + /* + * ESM procedure failed and, received message has been discarded or + * Status message has been returned; ignore ESM procedure failure + */ + rc = RETURNok; } LOG_FUNC_RETURN(rc); @@ -490,26 +484,26 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, /**************************************************************************** ** ** - ** Name: emm_proc_attach_reject() ** + ** Name: emm_proc_attach_reject() ** ** ** ** Description: Performs the attach procedure rejected by the network. ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.5 ** - ** Upon receiving the ATTACH REJECT message, the UE shall ** - ** stop timer T3410 and take actions depending on the EMM ** - ** cause value received. ** + ** Upon receiving the ATTACH REJECT message, the UE shall ** + ** stop timer T3410 and take actions depending on the EMM ** + ** cause value received. ** ** ** - ** Inputs: emm_cause: EMM cause indicating why the network re- ** - ** jected the attach request ** - ** esm_msg: PDN connectivity reject ESM message ** - ** Others: None ** + ** Inputs: emm_cause: EMM cause indicating why the network re- ** + ** jected the attach request ** + ** esm_msg: PDN connectivity reject ESM message ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _emm_attach_data, T3410 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data, _emm_attach_data, T3410 ** ** ** ***************************************************************************/ -int emm_proc_attach_reject(int emm_cause, const OctetString* esm_msg) +int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg) { LOG_FUNC_IN; @@ -517,7 +511,7 @@ int emm_proc_attach_reject(int emm_cause, const OctetString* esm_msg) int rc; LOG_TRACE(WARNING, "EMM-PROC - EPS attach rejected by the network, " - "EMM cause = %d", emm_cause); + "EMM cause = %d", emm_cause); /* Stop timer T3410 */ LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); @@ -525,167 +519,163 @@ int emm_proc_attach_reject(int emm_cause, const OctetString* esm_msg) /* Update the EPS update status, the GUTI, the visited registered TAI and * the eKSI */ - switch (emm_cause) - { - case EMM_CAUSE_ILLEGAL_UE: - case EMM_CAUSE_ILLEGAL_ME: - case EMM_CAUSE_EPS_NOT_ALLOWED: - case EMM_CAUSE_BOTH_NOT_ALLOWED: - case EMM_CAUSE_PLMN_NOT_ALLOWED: - case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: - case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: - case EMM_CAUSE_TA_NOT_ALLOWED: - case EMM_CAUSE_ROAMING_NOT_ALLOWED: - case EMM_CAUSE_NO_SUITABLE_CELLS: - /* Set the EPS update status to EU3 ROAMING NOT ALLOWED */ - _emm_data.status = EU3_ROAMING_NOT_ALLOWED; - /* Delete the GUTI */ - _emm_data.guti = NULL; - /* Delete the last visited registered TAI */ - _emm_data.tai = NULL; - /* Delete the eKSI */ - if (_emm_data.security) { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; - } - break; - - default : - break; + switch (emm_cause) { + case EMM_CAUSE_ILLEGAL_UE: + case EMM_CAUSE_ILLEGAL_ME: + case EMM_CAUSE_EPS_NOT_ALLOWED: + case EMM_CAUSE_BOTH_NOT_ALLOWED: + case EMM_CAUSE_PLMN_NOT_ALLOWED: + case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: + case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: + case EMM_CAUSE_TA_NOT_ALLOWED: + case EMM_CAUSE_ROAMING_NOT_ALLOWED: + case EMM_CAUSE_NO_SUITABLE_CELLS: + /* Set the EPS update status to EU3 ROAMING NOT ALLOWED */ + _emm_data.status = EU3_ROAMING_NOT_ALLOWED; + /* Delete the GUTI */ + _emm_data.guti = NULL; + /* Delete the last visited registered TAI */ + _emm_data.tai = NULL; + /* Delete the eKSI */ + if (_emm_data.security) { + _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + } + break; + + default : + break; } /* Update list of equivalents PLMNs and attach attempt counter */ - switch (emm_cause) - { - case EMM_CAUSE_ILLEGAL_UE: - case EMM_CAUSE_ILLEGAL_ME: - case EMM_CAUSE_EPS_NOT_ALLOWED: - case EMM_CAUSE_BOTH_NOT_ALLOWED: - /* Consider the USIM as invalid for EPS services */ - _emm_data.usim_is_valid = FALSE; - /* Delete the list of equivalent PLMNs */ - _emm_data.nvdata.eplmn.n_plmns = 0; - break; - - case EMM_CAUSE_PLMN_NOT_ALLOWED: - case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: - case EMM_CAUSE_ROAMING_NOT_ALLOWED: - /* Delete the list of equivalent PLMNs */ - _emm_data.nvdata.eplmn.n_plmns = 0; - /* Reset the attach attempt counter */ - _emm_attach_data.attempt_count = 0; - break; - - case EMM_CAUSE_TA_NOT_ALLOWED: - case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: - case EMM_CAUSE_NO_SUITABLE_CELLS: - /* Reset the attach attempt counter */ - _emm_attach_data.attempt_count = 0; - break; - - case EMM_CAUSE_ESM_FAILURE: - /* 3GPP TS 24.301, section 5.5.1.2.6, case d */ - if (_emm_data.NAS_SignallingPriority != 1) { - /* The UE is not configured for NAS signalling low priority; - * set the attach attempt counter to 5 */ - _emm_attach_data.attempt_count = EMM_ATTACH_COUNTER_MAX; - } - break; - - case EMM_CAUSE_SEMANTICALLY_INCORRECT: - case EMM_CAUSE_INVALID_MANDATORY_INFO: - case EMM_CAUSE_MESSAGE_TYPE_NOT_IMPLEMENTED: - case EMM_CAUSE_IE_NOT_IMPLEMENTED: - case EMM_CAUSE_PROTOCOL_ERROR: - /* 3GPP TS 24.301, section 5.5.1.2.6, case d - * Set the attach attempt counter to 5 */ - _emm_attach_data.attempt_count = EMM_ATTACH_COUNTER_MAX; - break; - - default : - break; + switch (emm_cause) { + case EMM_CAUSE_ILLEGAL_UE: + case EMM_CAUSE_ILLEGAL_ME: + case EMM_CAUSE_EPS_NOT_ALLOWED: + case EMM_CAUSE_BOTH_NOT_ALLOWED: + /* Consider the USIM as invalid for EPS services */ + _emm_data.usim_is_valid = FALSE; + /* Delete the list of equivalent PLMNs */ + _emm_data.nvdata.eplmn.n_plmns = 0; + break; + + case EMM_CAUSE_PLMN_NOT_ALLOWED: + case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: + case EMM_CAUSE_ROAMING_NOT_ALLOWED: + /* Delete the list of equivalent PLMNs */ + _emm_data.nvdata.eplmn.n_plmns = 0; + /* Reset the attach attempt counter */ + _emm_attach_data.attempt_count = 0; + break; + + case EMM_CAUSE_TA_NOT_ALLOWED: + case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: + case EMM_CAUSE_NO_SUITABLE_CELLS: + /* Reset the attach attempt counter */ + _emm_attach_data.attempt_count = 0; + break; + + case EMM_CAUSE_ESM_FAILURE: + /* 3GPP TS 24.301, section 5.5.1.2.6, case d */ + if (_emm_data.NAS_SignallingPriority != 1) { + /* The UE is not configured for NAS signalling low priority; + * set the attach attempt counter to 5 */ + _emm_attach_data.attempt_count = EMM_ATTACH_COUNTER_MAX; + } + break; + + case EMM_CAUSE_SEMANTICALLY_INCORRECT: + case EMM_CAUSE_INVALID_MANDATORY_INFO: + case EMM_CAUSE_MESSAGE_TYPE_NOT_IMPLEMENTED: + case EMM_CAUSE_IE_NOT_IMPLEMENTED: + case EMM_CAUSE_PROTOCOL_ERROR: + /* 3GPP TS 24.301, section 5.5.1.2.6, case d + * Set the attach attempt counter to 5 */ + _emm_attach_data.attempt_count = EMM_ATTACH_COUNTER_MAX; + break; + + default : + break; } /* Update "forbidden lists" */ - switch (emm_cause) - { - case EMM_CAUSE_PLMN_NOT_ALLOWED: - case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: - /* Store the PLMN identity in the "forbidden PLMN list" */ - _emm_data.fplmn.plmn[_emm_data.fplmn.n_plmns++] = _emm_data.splmn; - break; - - case EMM_CAUSE_TA_NOT_ALLOWED: - /* Store the current TAI in the list of "forbidden tracking - * areas for regional provision of service" */ - _emm_data.ftai.tai[_emm_data.ftai.n_tais++] = *_emm_data.tai; - break; - - case EMM_CAUSE_ROAMING_NOT_ALLOWED: - /* Store the current TAI in the list of "forbidden tracking - * areas for roaming" */ - _emm_data.ftai_roaming.tai[_emm_data.ftai_roaming.n_tais++] = *_emm_data.tai; - break; - - case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: - /* Store the PLMN identity in the "forbidden PLMNs for GPRS - * service" list */ - _emm_data.fplmn_gprs.plmn[_emm_data.fplmn_gprs.n_plmns++] = _emm_data.splmn; - break; - - default : - break; + switch (emm_cause) { + case EMM_CAUSE_PLMN_NOT_ALLOWED: + case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: + /* Store the PLMN identity in the "forbidden PLMN list" */ + _emm_data.fplmn.plmn[_emm_data.fplmn.n_plmns++] = _emm_data.splmn; + break; + + case EMM_CAUSE_TA_NOT_ALLOWED: + /* Store the current TAI in the list of "forbidden tracking + * areas for regional provision of service" */ + _emm_data.ftai.tai[_emm_data.ftai.n_tais++] = *_emm_data.tai; + break; + + case EMM_CAUSE_ROAMING_NOT_ALLOWED: + /* Store the current TAI in the list of "forbidden tracking + * areas for roaming" */ + _emm_data.ftai_roaming.tai[_emm_data.ftai_roaming.n_tais++] = *_emm_data.tai; + break; + + case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: + /* Store the PLMN identity in the "forbidden PLMNs for GPRS + * service" list */ + _emm_data.fplmn_gprs.plmn[_emm_data.fplmn_gprs.n_plmns++] = _emm_data.splmn; + break; + + default : + break; } /* Update state of EMM sublayer */ - switch (emm_cause) - { - case EMM_CAUSE_ILLEGAL_UE: - case EMM_CAUSE_ILLEGAL_ME: - case EMM_CAUSE_EPS_NOT_ALLOWED: - case EMM_CAUSE_BOTH_NOT_ALLOWED: - /* - * Notify EMM that EPS attach is rejected - */ - emm_sap.primitive = EMMREG_ATTACH_REJ; - break; - - case EMM_CAUSE_PLMN_NOT_ALLOWED: - case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: - case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: - /* - * Notify EMM that the UE has to perform a PLMN selection because - * it is not allowed to operate in the currently selected PLMN - */ - emm_sap.primitive = EMMREG_REGISTER_REQ; - break; - - case EMM_CAUSE_TA_NOT_ALLOWED: - case EMM_CAUSE_ROAMING_NOT_ALLOWED: - case EMM_CAUSE_NO_SUITABLE_CELLS: - /* - * Notify EMM that the UE failed to register to the network for - * EPS services because it is not allowed to operate in the - * requested tracking area - */ - emm_sap.primitive = EMMREG_REGISTER_REJ; - break; - - case EMM_CAUSE_IMEI_NOT_ACCEPTED: - if (_emm_data.is_emergency) { - /* - * Notify EMM that the UE failed to register to the network - * for emergency bearer services because "IMEI not accepted" - */ - emm_sap.primitive = EMMREG_NO_IMSI; - break; - } - /* break is volontary missing */ - - default : - /* Other values are considered as abnormal cases - * 3GPP TS 24.301, section 5.5.1.2.6, case d */ - _emm_attach_abnormal_cases_bcd(&emm_sap); - break; + switch (emm_cause) { + case EMM_CAUSE_ILLEGAL_UE: + case EMM_CAUSE_ILLEGAL_ME: + case EMM_CAUSE_EPS_NOT_ALLOWED: + case EMM_CAUSE_BOTH_NOT_ALLOWED: + /* + * Notify EMM that EPS attach is rejected + */ + emm_sap.primitive = EMMREG_ATTACH_REJ; + break; + + case EMM_CAUSE_PLMN_NOT_ALLOWED: + case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: + case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: + /* + * Notify EMM that the UE has to perform a PLMN selection because + * it is not allowed to operate in the currently selected PLMN + */ + emm_sap.primitive = EMMREG_REGISTER_REQ; + break; + + case EMM_CAUSE_TA_NOT_ALLOWED: + case EMM_CAUSE_ROAMING_NOT_ALLOWED: + case EMM_CAUSE_NO_SUITABLE_CELLS: + /* + * Notify EMM that the UE failed to register to the network for + * EPS services because it is not allowed to operate in the + * requested tracking area + */ + emm_sap.primitive = EMMREG_REGISTER_REJ; + break; + + case EMM_CAUSE_IMEI_NOT_ACCEPTED: + if (_emm_data.is_emergency) { + /* + * Notify EMM that the UE failed to register to the network + * for emergency bearer services because "IMEI not accepted" + */ + emm_sap.primitive = EMMREG_NO_IMSI; + break; + } + /* break is volontary missing */ + + default : + /* Other values are considered as abnormal cases + * 3GPP TS 24.301, section 5.5.1.2.6, case d */ + _emm_attach_abnormal_cases_bcd(&emm_sap); + break; } rc = emm_sap_send(&emm_sap); @@ -694,11 +684,11 @@ int emm_proc_attach_reject(int emm_cause, const OctetString* esm_msg) * Notify ESM that the network rejected connectivity to the PDN */ if (esm_msg != NULL) { - esm_sap_t esm_sap; - esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; - esm_sap.is_standalone = FALSE; - esm_sap.recv = esm_msg; - rc = esm_sap_send(&esm_sap); + esm_sap_t esm_sap; + esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; + esm_sap.is_standalone = FALSE; + esm_sap.recv = esm_msg; + rc = esm_sap_send(&esm_sap); } LOG_FUNC_RETURN(rc); @@ -706,26 +696,26 @@ int emm_proc_attach_reject(int emm_cause, const OctetString* esm_msg) /**************************************************************************** ** ** - ** Name: emm_proc_attach_complete() ** + ** Name: emm_proc_attach_complete() ** ** ** ** Description: Terminates the attach procedure when Attach Complete mes- ** - ** sage has been successfully delivered to the MME. ** + ** 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. ** + ** 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 ** + ** Inputs: args: Not used ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _emm_attach_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data, _emm_attach_data ** ** ** ***************************************************************************/ -int emm_proc_attach_complete(void* args) +int emm_proc_attach_complete(void *args) { LOG_FUNC_IN; @@ -754,14 +744,14 @@ int emm_proc_attach_complete(void* args) 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); + /* + * 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); @@ -769,29 +759,29 @@ int emm_proc_attach_complete(void* args) /**************************************************************************** ** ** - ** Name: emm_proc_attach_failure() ** + ** Name: emm_proc_attach_failure() ** ** ** ** Description: Performs the attach procedure abnormal case upon receipt ** - ** of transmission failure of Attach Request message or At- ** - ** tach Complete message. ** + ** of transmission failure of Attach Request message or At- ** + ** tach Complete message. ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.6, cases h and i ** - ** The UE shall restart the attach procedure when timer ** - ** T3411 expires. ** + ** The UE shall restart the attach procedure when timer ** + ** T3411 expires. ** ** ** - ** Inputs: is_initial: TRUE if the NAS message that failed to be ** - ** transfered is an initial NAS message (ESM ** - ** message embedded within an Attach Request ** - ** message) ** - ** args: Not used ** - ** Others: None ** + ** Inputs: is_initial: TRUE if the NAS message that failed to be ** + ** transfered is an initial NAS message (ESM ** + ** message embedded within an Attach Request ** + ** message) ** + ** args: Not used ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3410, T3411 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3410, T3411 ** ** ** ***************************************************************************/ -int emm_proc_attach_failure(int is_initial, void* args) +int emm_proc_attach_failure(int is_initial, void *args) { LOG_FUNC_IN; @@ -805,37 +795,36 @@ int emm_proc_attach_failure(int is_initial, void* args) /* Stop timer T3410 if still running */ if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); + T3410.id = nas_timer_stop(T3410.id); } if (is_initial) { - /* - * Notify ESM that the PDN CONNECTIVITY REQUEST message contained - * in the ESM message container IE of the ATTACH REQUEST has failed - * to be transmitted - */ - esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; - esm_sap.is_standalone = FALSE; - esm_sap.recv = NULL; - } - else { - /* - * Notify ESM that ACTIVATE DEFAULT EPS BEARER CONTEXT REQUEST message - * contained in the ESM message container IE of the ATTACH COMPLETE - * has failed to be transmitted - */ - esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REJ; - esm_sap.is_standalone = FALSE; - esm_sap.recv = NULL; + /* + * Notify ESM that the PDN CONNECTIVITY REQUEST message contained + * in the ESM message container IE of the ATTACH REQUEST has failed + * to be transmitted + */ + esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; + esm_sap.is_standalone = FALSE; + esm_sap.recv = NULL; + } else { + /* + * Notify ESM that ACTIVATE DEFAULT EPS BEARER CONTEXT REQUEST message + * contained in the ESM message container IE of the ATTACH COMPLETE + * has failed to be transmitted + */ + esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REJ; + esm_sap.is_standalone = FALSE; + esm_sap.recv = NULL; } rc = esm_sap_send(&esm_sap); if (rc != RETURNerror) { - /* Start T3411 timer */ - T3411.id = nas_timer_start(T3411.sec, _emm_attach_t3411_handler, NULL); - LOG_TRACE(INFO, "EMM-PROC - Timer T3411 (%d) expires in %ld seconds", - T3411.id, T3411.sec); + /* Start T3411 timer */ + T3411.id = nas_timer_start(T3411.sec, _emm_attach_t3411_handler, NULL); + LOG_TRACE(INFO, "EMM-PROC - Timer T3411 (%d) expires in %ld seconds", + T3411.id, T3411.sec); } LOG_FUNC_RETURN(rc); @@ -843,24 +832,24 @@ int emm_proc_attach_failure(int is_initial, void* args) /**************************************************************************** ** ** - ** Name: emm_proc_attach_release() ** + ** Name: emm_proc_attach_release() ** ** ** ** Description: Performs the attach procedure abnormal case upon receipt ** - ** of NAS signalling connection release indication. ** + ** 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. ** + ** The attach procedure shall be aborted and the UE shall ** + ** execute abnormal case attach procedure. ** ** ** - ** Inputs: args: Not used ** - ** Others: None ** + ** Inputs: args: Not used ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_attach_release(void* args) +int emm_proc_attach_release(void *args) { LOG_FUNC_IN; @@ -879,16 +868,16 @@ int emm_proc_attach_release(void* args) /**************************************************************************** ** ** - ** Name: emm_proc_attach_restart() ** + ** Name: emm_proc_attach_restart() ** ** ** ** Description: Restarts the attach procedure ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_attach_restart(void) @@ -912,16 +901,16 @@ int emm_proc_attach_restart(void) /**************************************************************************** ** ** - ** Name: emm_proc_attach_set_emergency() ** + ** Name: emm_proc_attach_set_emergency() ** ** ** ** Description: Set the emergency bearer services indicator ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ int emm_proc_attach_set_emergency(void) @@ -929,7 +918,7 @@ int emm_proc_attach_set_emergency(void) LOG_FUNC_IN; LOG_TRACE(WARNING, "EMM-PROC - UE is now attached to the network for " - "emergency bearer services only"); + "emergency bearer services only"); _emm_data.is_emergency = TRUE; @@ -938,17 +927,17 @@ int emm_proc_attach_set_emergency(void) /**************************************************************************** ** ** - ** Name: emm_proc_attach_set_detach() ** + ** Name: emm_proc_attach_set_detach() ** ** ** ** Description: Reset the network attachment indicator and enter state ** - ** EMM-DEREGISTERED + ** EMM-DEREGISTERED ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ int emm_proc_attach_set_detach(void) @@ -958,7 +947,7 @@ int emm_proc_attach_set_detach(void) int rc; LOG_TRACE(WARNING, - "EMM-PROC - UE is now locally detached from the network"); + "EMM-PROC - UE is now locally detached from the network"); /* Reset the network attachment indicator */ _emm_data.is_attached = FALSE; @@ -976,49 +965,49 @@ int emm_proc_attach_set_detach(void) /* * -------------------------------------------------------------------------- - * Attach procedure executed by the MME + * Attach procedure executed by the MME * -------------------------------------------------------------------------- */ #ifdef NAS_MME /**************************************************************************** ** ** - ** Name: emm_proc_attach_request() ** + ** Name: emm_proc_attach_request() ** ** ** ** Description: Performs the UE requested attach procedure ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.3 ** - ** The network may initiate EMM common procedures, e.g. the ** - ** identification, authentication and security mode control ** - ** procedures during the attach procedure, depending on the ** - ** information received in the ATTACH REQUEST message (e.g. ** - ** IMSI, GUTI and KSI). ** - ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** type: Type of the requested attach ** - ** native_ksi: TRUE if the security context is of type ** - ** native (for KSIASME) ** - ** ksi: The NAS ket sey identifier ** - ** native_guti: TRUE if the provided GUTI is native GUTI ** - ** guti: The GUTI if provided by the UE ** - ** imsi: The IMSI if provided by the UE ** - ** imei: The IMEI if provided by the UE ** - ** tai: Identifies the last visited tracking area ** - ** the UE is registered to ** - ** eea: Supported EPS encryption algorithms ** - ** eia: Supported EPS integrity algorithms ** - ** esm_msg: PDN connectivity request ESM message ** - ** Others: _emm_data ** - ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** The network may initiate EMM common procedures, e.g. the ** + ** identification, authentication and security mode control ** + ** procedures during the attach procedure, depending on the ** + ** information received in the ATTACH REQUEST message (e.g. ** + ** IMSI, GUTI and KSI). ** + ** ** + ** Inputs: ueid: UE lower layer identifier ** + ** type: Type of the requested attach ** + ** native_ksi: TRUE if the security context is of type ** + ** native (for KSIASME) ** + ** ksi: The NAS ket sey identifier ** + ** native_guti: TRUE if the provided GUTI is native GUTI ** + ** guti: The GUTI if provided by the UE ** + ** imsi: The IMSI if provided by the UE ** + ** imei: The IMEI if provided by the UE ** + ** tai: Identifies the last visited tracking area ** + ** the UE is registered to ** + ** eea: Supported EPS encryption algorithms ** + ** eia: Supported EPS integrity algorithms ** + ** esm_msg: PDN connectivity request ESM message ** + ** Others: _emm_data ** + ** ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, - int native_ksi, int ksi, int native_guti, - GUTI_t* guti, imsi_t* imsi, imei_t* imei, - tai_t* tai, int eea, int eia, - const OctetString* esm_msg) + int native_ksi, int ksi, int native_guti, + GUTI_t *guti, imsi_t *imsi, imei_t *imei, + tai_t *tai, int eea, int eia, + const OctetString *esm_msg) { LOG_FUNC_IN; @@ -1049,8 +1038,7 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, * emergency attach". */ if ( !(_emm_data.conf.features & MME_API_EMERGENCY_ATTACH) && - (type == EMM_ATTACH_TYPE_EMERGENCY) ) - { + (type == EMM_ATTACH_TYPE_EMERGENCY) ) { ue_ctx.emm_cause = EMM_CAUSE_IMEI_NOT_ACCEPTED; /* Do not accept the UE to attach for emergency services */ rc = _emm_attach_reject(&ue_ctx); @@ -1058,10 +1046,10 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, } /* Get the UE's EMM context if it exists */ - emm_data_context_t** emm_ctx = NULL; + emm_data_context_t **emm_ctx = NULL; #if defined(EPC_BUILD) - emm_data_context_t* temp = NULL; + emm_data_context_t *temp = NULL; temp = emm_data_context_get(&_emm_data, ueid); emm_ctx = &temp; @@ -1070,62 +1058,59 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, #endif if (*emm_ctx != NULL) { - /* An EMM context already exists for the UE in the network */ - if (_emm_attach_have_changed(*emm_ctx, type, ksi, guti, imsi, imei, - eea, eia)) - { - /* - * 3GPP TS 24.301, section 5.5.1.2.7, abnormal case e - * The attach parameters have changed from the one received within - * the previous Attach Request message; - * the previously initiated attach procedure shall be aborted and - * the new attach procedure shall be executed; - */ - LOG_TRACE(WARNING, "EMM-PROC - Attach parameters have changed"); - /* - * Notify EMM that the attach procedure is aborted - */ - emm_sap_t emm_sap; - emm_sap.primitive = EMMREG_PROC_ABORT; - emm_sap.u.emm_reg.ueid = ueid; + /* An EMM context already exists for the UE in the network */ + if (_emm_attach_have_changed(*emm_ctx, type, ksi, guti, imsi, imei, + eea, eia)) { + /* + * 3GPP TS 24.301, section 5.5.1.2.7, abnormal case e + * The attach parameters have changed from the one received within + * the previous Attach Request message; + * the previously initiated attach procedure shall be aborted and + * the new attach procedure shall be executed; + */ + LOG_TRACE(WARNING, "EMM-PROC - Attach parameters have changed"); + /* + * Notify EMM that the attach procedure is aborted + */ + emm_sap_t emm_sap; + emm_sap.primitive = EMMREG_PROC_ABORT; + emm_sap.u.emm_reg.ueid = ueid; emm_sap.u.emm_reg.ctx = *emm_ctx; - rc = emm_sap_send(&emm_sap); - - if (rc != RETURNerror) { - /* Process new attach procedure */ - LOG_TRACE(WARNING, "EMM-PROC - Initiate new attach procedure"); - rc = emm_proc_attach_request(ueid, type, native_ksi, ksi, - native_guti, guti, imsi, imei, - tai, eea, eia, esm_msg); - } - LOG_FUNC_RETURN(rc); - } - else { - /* Continue with the previous attach procedure */ - LOG_TRACE(WARNING, "EMM-PROC - Received duplicated Attach Request"); - LOG_FUNC_RETURN(RETURNok); - } - } - else { - /* Create UE's EMM context */ - *emm_ctx = (emm_data_context_t*)malloc(sizeof(emm_data_context_t)); - if (emm_ctx == NULL) { - LOG_TRACE(WARNING, "EMM-PROC - Failed to create EMM context"); - ue_ctx.emm_cause = EMM_CAUSE_ILLEGAL_UE; - /* Do not accept the UE to attach to the network */ - rc = _emm_attach_reject(&ue_ctx); - LOG_FUNC_RETURN(rc); - } - (*emm_ctx)->is_dynamic = TRUE; - (*emm_ctx)->guti = NULL; - (*emm_ctx)->old_guti = NULL; - (*emm_ctx)->imsi = NULL; - (*emm_ctx)->imei = NULL; - (*emm_ctx)->security = NULL; - (*emm_ctx)->esm_msg.length = 0; - (*emm_ctx)->esm_msg.value = NULL; - (*emm_ctx)->emm_cause = EMM_CAUSE_SUCCESS; + rc = emm_sap_send(&emm_sap); + + if (rc != RETURNerror) { + /* Process new attach procedure */ + LOG_TRACE(WARNING, "EMM-PROC - Initiate new attach procedure"); + rc = emm_proc_attach_request(ueid, type, native_ksi, ksi, + native_guti, guti, imsi, imei, + tai, eea, eia, esm_msg); + } + LOG_FUNC_RETURN(rc); + } else { + /* Continue with the previous attach procedure */ + LOG_TRACE(WARNING, "EMM-PROC - Received duplicated Attach Request"); + LOG_FUNC_RETURN(RETURNok); + } + } else { + /* Create UE's EMM context */ + *emm_ctx = (emm_data_context_t *)malloc(sizeof(emm_data_context_t)); + if (emm_ctx == NULL) { + LOG_TRACE(WARNING, "EMM-PROC - Failed to create EMM context"); + ue_ctx.emm_cause = EMM_CAUSE_ILLEGAL_UE; + /* Do not accept the UE to attach to the network */ + rc = _emm_attach_reject(&ue_ctx); + LOG_FUNC_RETURN(rc); + } + (*emm_ctx)->is_dynamic = TRUE; + (*emm_ctx)->guti = NULL; + (*emm_ctx)->old_guti = NULL; + (*emm_ctx)->imsi = NULL; + (*emm_ctx)->imei = NULL; + (*emm_ctx)->security = NULL; + (*emm_ctx)->esm_msg.length = 0; + (*emm_ctx)->esm_msg.value = NULL; + (*emm_ctx)->emm_cause = EMM_CAUSE_SUCCESS; (*emm_ctx)->_emm_fsm_status = EMM_DEREGISTERED; @@ -1136,19 +1121,18 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, /* Update the EMM context with the current attach procedure parameters */ rc = _emm_attach_update(*emm_ctx, ueid, type, ksi, guti, imsi, imei, - eea, eia, esm_msg); + eea, eia, esm_msg); if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-PROC - Failed to update EMM context"); - /* Do not accept the UE to attach to the network */ - (*emm_ctx)->ueid = ueid; - (*emm_ctx)->emm_cause = EMM_CAUSE_ILLEGAL_UE; - rc = _emm_attach_reject(*emm_ctx); - } - else { - /* - * Performs UE identification - */ - rc = _emm_attach_identify(*emm_ctx); + LOG_TRACE(WARNING, "EMM-PROC - Failed to update EMM context"); + /* Do not accept the UE to attach to the network */ + (*emm_ctx)->ueid = ueid; + (*emm_ctx)->emm_cause = EMM_CAUSE_ILLEGAL_UE; + rc = _emm_attach_reject(*emm_ctx); + } else { + /* + * Performs UE identification + */ + rc = _emm_attach_identify(*emm_ctx); } LOG_FUNC_RETURN(rc); @@ -1156,21 +1140,21 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, /**************************************************************************** ** ** - ** Name: emm_proc_attach_reject() ** + ** Name: emm_proc_attach_reject() ** ** ** ** Description: Performs the protocol error abnormal case ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.7, case b ** - ** If the ATTACH REQUEST message is received with a protocol ** - ** error, the network shall return an ATTACH REJECT message. ** + ** If the ATTACH REQUEST message is received with a protocol ** + ** error, the network shall return an ATTACH REJECT message. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** emm_cause: EMM cause code to be reported ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** emm_cause: EMM cause code to be reported ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ int emm_proc_attach_reject(unsigned int ueid, int emm_cause) @@ -1205,27 +1189,27 @@ int emm_proc_attach_reject(unsigned int ueid, int emm_cause) /**************************************************************************** ** ** - ** Name: emm_proc_attach_complete() ** + ** Name: emm_proc_attach_complete() ** ** ** ** Description: Terminates the attach procedure upon receiving Attach ** - ** Complete message from the UE. ** + ** Complete message from the UE. ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.4 ** - ** Upon receiving an ATTACH COMPLETE message, the MME shall ** - ** stop timer T3450, enter state EMM-REGISTERED and consider ** - ** the GUTI sent in the ATTACH ACCEPT message as valid. ** + ** Upon receiving an ATTACH COMPLETE message, the MME shall ** + ** stop timer T3450, enter state EMM-REGISTERED and consider ** + ** the GUTI sent in the ATTACH ACCEPT message as valid. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** esm_msg: Activate default EPS bearer context accept ** - ** ESM message ** - ** Others: _emm_data ** + ** Inputs: ueid: UE lower layer identifier ** + ** esm_msg: Activate default EPS bearer context accept ** + ** ESM message ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, T3450 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data, T3450 ** ** ** ***************************************************************************/ -int emm_proc_attach_complete(unsigned int ueid, const OctetString* esm_msg) +int emm_proc_attach_complete(unsigned int ueid, const OctetString *esm_msg) { LOG_FUNC_IN; @@ -1240,16 +1224,16 @@ int emm_proc_attach_complete(unsigned int ueid, const OctetString* esm_msg) T3450.id = nas_timer_stop(T3450.id); /* Release retransmission timer parameters */ - attach_data_t* data = (attach_data_t*)(emm_proc_common_get_args(ueid)); + attach_data_t *data = (attach_data_t *)(emm_proc_common_get_args(ueid)); if (data) { - if (data->esm_msg.length > 0) { - free(data->esm_msg.value); - } - free(data); + if (data->esm_msg.length > 0) { + free(data->esm_msg.value); + } + free(data); } /* Get the UE context */ - emm_data_context_t* emm_ctx = NULL; + emm_data_context_t *emm_ctx = NULL; #if defined(EPC_BUILD) if (ueid > 0) { @@ -1257,59 +1241,56 @@ int emm_proc_attach_complete(unsigned int ueid, const OctetString* esm_msg) } #else if (ueid < EMM_DATA_NB_UE_MAX) { - emm_ctx = _emm_data.ctx[ueid]; + emm_ctx = _emm_data.ctx[ueid]; } #endif if (emm_ctx) { - /* Delete the old GUTI and consider the GUTI sent in the Attach - * Accept message as valid */ - emm_ctx->guti_is_new = FALSE; - emm_ctx->old_guti = NULL; - /* - * Forward the Activate Default EPS Bearer Context Accept message - * to the EPS session management sublayer - */ - esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_CNF; - esm_sap.is_standalone = FALSE; - esm_sap.ueid = ueid; - esm_sap.recv = esm_msg; - rc = esm_sap_send(&esm_sap); - } - else { - LOG_TRACE(ERROR, "EMM-PROC - No EMM context exists"); + /* Delete the old GUTI and consider the GUTI sent in the Attach + * Accept message as valid */ + emm_ctx->guti_is_new = FALSE; + emm_ctx->old_guti = NULL; + /* + * Forward the Activate Default EPS Bearer Context Accept message + * to the EPS session management sublayer + */ + esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_CNF; + esm_sap.is_standalone = FALSE; + esm_sap.ueid = ueid; + esm_sap.recv = esm_msg; + rc = esm_sap_send(&esm_sap); + } else { + LOG_TRACE(ERROR, "EMM-PROC - No EMM context exists"); } if ( (rc != RETURNerror) && (esm_sap.err == ESM_SAP_SUCCESS) ) { - /* Set the network attachment indicator */ - emm_ctx->is_attached = TRUE; - /* - * Notify EMM that attach procedure has successfully completed - */ - emm_sap.primitive = EMMREG_ATTACH_CNF; - emm_sap.u.emm_reg.ueid = ueid; - rc = emm_sap_send(&emm_sap); - } - else if (esm_sap.err != ESM_SAP_DISCARDED) { - /* - * Notify EMM that attach procedure failed - */ - emm_sap.primitive = EMMREG_ATTACH_REJ; - emm_sap.u.emm_reg.ueid = ueid; - rc = emm_sap_send(&emm_sap); - } - else { - /* - * ESM procedure failed and, received message has been discarded or - * Status message has been returned; ignore ESM procedure failure - */ - rc = RETURNok; + /* Set the network attachment indicator */ + emm_ctx->is_attached = TRUE; + /* + * Notify EMM that attach procedure has successfully completed + */ + emm_sap.primitive = EMMREG_ATTACH_CNF; + emm_sap.u.emm_reg.ueid = ueid; + rc = emm_sap_send(&emm_sap); + } else if (esm_sap.err != ESM_SAP_DISCARDED) { + /* + * Notify EMM that attach procedure failed + */ + emm_sap.primitive = EMMREG_ATTACH_REJ; + emm_sap.u.emm_reg.ueid = ueid; + rc = emm_sap_send(&emm_sap); + } else { + /* + * ESM procedure failed and, received message has been discarded or + * Status message has been returned; ignore ESM procedure failure + */ + rc = RETURNok; } LOG_FUNC_RETURN(rc); } -#endif // NAS_MME +#endif // NAS_MME /****************************************************************************/ /********************* L O C A L F U N C T I O N S *********************/ @@ -1318,31 +1299,31 @@ int emm_proc_attach_complete(unsigned int ueid, const OctetString* esm_msg) #ifdef NAS_UE /* * -------------------------------------------------------------------------- - * Timer handlers + * Timer handlers * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _emm_attach_t3410_handler() ** + ** 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. ** + ** 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 ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: T3410 ** + ** Outputs: None ** + ** Return: None ** + ** Others: T3410 ** ** ** ***************************************************************************/ -void* _emm_attach_t3410_handler(void* args) +void *_emm_attach_t3410_handler(void *args) { LOG_FUNC_IN; @@ -1358,8 +1339,8 @@ void* _emm_attach_t3410_handler(void* args) rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { - /* Locally release the NAS signalling connection */ - _emm_data.ecm_status = ECM_IDLE; + /* Locally release the NAS signalling connection */ + _emm_data.ecm_status = ECM_IDLE; } LOG_FUNC_RETURN(NULL); @@ -1367,23 +1348,23 @@ void* _emm_attach_t3410_handler(void* args) /**************************************************************************** ** ** - ** Name: _emm_attach_t3411_handler() ** + ** 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. ** + ** Upon T3411 timer expiration, the attach procedure shall ** + ** be restarted, if still required by ESM sublayer. ** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: T3411 ** + ** Outputs: None ** + ** Return: None ** + ** Others: T3411 ** ** ** ***************************************************************************/ -static void* _emm_attach_t3411_handler(void* args) +static void *_emm_attach_t3411_handler(void *args) { LOG_FUNC_IN; @@ -1407,27 +1388,27 @@ static void* _emm_attach_t3411_handler(void* args) /**************************************************************************** ** ** - ** Name: _emm_attach_t3402_handler() ** + ** Name: _emm_attach_t3402_handler() ** ** ** ** Description: T3402 timeout handler ** ** ** - ** Upon T3402 timer expiration: ** + ** Upon T3402 timer expiration: ** ** 3GPP TS 24.301, section 5.5.1.1 ** - ** the attach attempt counter shall be reset when the UE is ** - ** in substate DEREGISTERED.ATTEMPTING-TO-ATTACH; ** + ** the attach attempt counter shall be reset when the UE is ** + ** in substate DEREGISTERED.ATTEMPTING-TO-ATTACH; ** ** 3GPP TS 24.301, section 5.2.2.3.3 ** - ** the UE shall initiate an attach or combined attach proce- ** - ** dure in substate DEREGISTERED.ATTEMPTING-TO-ATTACH; ** + ** the UE shall initiate an attach or combined attach proce- ** + ** dure in substate DEREGISTERED.ATTEMPTING-TO-ATTACH; ** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: _emm_attach_data, T3402 ** + ** Outputs: None ** + ** Return: None ** + ** Others: _emm_attach_data, T3402 ** ** ** ***************************************************************************/ -static void* _emm_attach_t3402_handler(void* args) +static void *_emm_attach_t3402_handler(void *args) { LOG_FUNC_IN; @@ -1453,83 +1434,82 @@ static void* _emm_attach_t3402_handler(void* args) /* * -------------------------------------------------------------------------- - * Abnormal cases in the UE + * Abnormal cases in the UE * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _emm_attach_abnormal_cases_bcd() ** + ** Name: _emm_attach_abnormal_cases_bcd() ** ** ** ** Description: Performs the abnormal case attach procedure. ** ** ** - ** 3GPP TS 24.301, section 5.5.1.2.6, cases b, c and d ** - ** The Timer T3410 shall be stopped if still running, the ** - ** attach attempt counter shall be incremented and the UE ** - ** shall proceed depending on whether the attach attempt ** - ** counter reached its maximum value or not. ** + ** 3GPP TS 24.301, section 5.5.1.2.6, cases b, c and d ** + ** The Timer T3410 shall be stopped if still running, the ** + ** attach attempt counter shall be incremented and the UE ** + ** shall proceed depending on whether the attach attempt ** + ** counter reached its maximum value or not. ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: emm_sap: EMM service access point ** - ** Return: None ** - ** Others: _emm_data, _emm_attach_data, T3402, T3410, ** - ** T3411 ** + ** Outputs: emm_sap: EMM service access point ** + ** Return: None ** + ** Others: _emm_data, _emm_attach_data, T3402, T3410, ** + ** T3411 ** ** ** ***************************************************************************/ -static void _emm_attach_abnormal_cases_bcd(emm_sap_t* emm_sap) +static void _emm_attach_abnormal_cases_bcd(emm_sap_t *emm_sap) { LOG_FUNC_IN; LOG_TRACE(WARNING, "EMM-PROC - Abnormal case, attach counter = %d", - _emm_attach_data.attempt_count); + _emm_attach_data.attempt_count); /* Stop timer T3410 */ if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); + T3410.id = nas_timer_stop(T3410.id); } if (_emm_attach_data.attempt_count < EMM_ATTACH_COUNTER_MAX) { - /* Increment the attach attempt counter */ - _emm_attach_data.attempt_count += 1; - /* Start T3411 timer */ - T3411.id = nas_timer_start(T3411.sec, _emm_attach_t3411_handler, NULL); - LOG_TRACE(INFO, "EMM-PROC - Timer T3411 (%d) expires in %ld seconds", - T3411.id, T3411.sec); - /* - * Notify EMM that the attempt to attach for EPS services failed and - * the attach attempt counter didn't reach its maximum value; network - * attach procedure shall be restarted when timer T3411 expires. - */ - emm_sap->primitive = EMMREG_ATTACH_FAILED; - } - else { - /* Delete the GUTI */ - _emm_data.guti = NULL; - /* Delete the TAI list */ - _emm_data.ltai.n_tais = 0; - /* Delete the last visited registered TAI */ - _emm_data.tai = NULL; - /* Delete the list of equivalent PLMNs */ - _emm_data.nvdata.eplmn.n_plmns = 0; - /* Delete the eKSI */ - if (_emm_data.security) { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; - } - /* Set the EPS update status to EU2 NOT UPDATED */ - _emm_data.status = EU2_NOT_UPDATED; - - /* Start T3402 timer */ - T3402.id = nas_timer_start(T3402.sec, _emm_attach_t3402_handler, NULL); - LOG_TRACE(INFO, "EMM-PROC - Timer T3402 (%d) expires in %ld seconds", - T3402.id, T3402.sec); - /* - * Notify EMM that the attempt to attach for EPS services failed and - * the attach attempt counter reached its maximum value. - */ - emm_sap->primitive = EMMREG_ATTACH_EXCEEDED; + /* Increment the attach attempt counter */ + _emm_attach_data.attempt_count += 1; + /* Start T3411 timer */ + T3411.id = nas_timer_start(T3411.sec, _emm_attach_t3411_handler, NULL); + LOG_TRACE(INFO, "EMM-PROC - Timer T3411 (%d) expires in %ld seconds", + T3411.id, T3411.sec); + /* + * Notify EMM that the attempt to attach for EPS services failed and + * the attach attempt counter didn't reach its maximum value; network + * attach procedure shall be restarted when timer T3411 expires. + */ + emm_sap->primitive = EMMREG_ATTACH_FAILED; + } else { + /* Delete the GUTI */ + _emm_data.guti = NULL; + /* Delete the TAI list */ + _emm_data.ltai.n_tais = 0; + /* Delete the last visited registered TAI */ + _emm_data.tai = NULL; + /* Delete the list of equivalent PLMNs */ + _emm_data.nvdata.eplmn.n_plmns = 0; + /* Delete the eKSI */ + if (_emm_data.security) { + _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + } + /* Set the EPS update status to EU2 NOT UPDATED */ + _emm_data.status = EU2_NOT_UPDATED; + + /* Start T3402 timer */ + T3402.id = nas_timer_start(T3402.sec, _emm_attach_t3402_handler, NULL); + LOG_TRACE(INFO, "EMM-PROC - Timer T3402 (%d) expires in %ld seconds", + T3402.id, T3402.sec); + /* + * Notify EMM that the attempt to attach for EPS services failed and + * the attach attempt counter reached its maximum value. + */ + emm_sap->primitive = EMMREG_ATTACH_EXCEEDED; } LOG_FUNC_OUT; @@ -1539,48 +1519,48 @@ static void _emm_attach_abnormal_cases_bcd(emm_sap_t* emm_sap) #ifdef NAS_MME /* * -------------------------------------------------------------------------- - * Timer handlers + * Timer handlers * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _emm_attach_t3450_handler() ** + ** Name: _emm_attach_t3450_handler() ** ** ** ** Description: T3450 timeout handler ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.7, case c ** - ** On the first expiry of the timer T3450, the network shall ** - ** retransmit the ATTACH ACCEPT message and shall reset and ** - ** restart timer T3450. This retransmission is repeated four ** - ** times, i.e. on the fifth expiry of timer T3450, the at- ** - ** tach procedure shall be aborted and the MME enters state ** - ** EMM-DEREGISTERED. ** + ** On the first expiry of the timer T3450, the network shall ** + ** retransmit the ATTACH ACCEPT message and shall reset and ** + ** restart timer T3450. This retransmission is repeated four ** + ** times, i.e. on the fifth expiry of timer T3450, the at- ** + ** tach procedure shall be aborted and the MME enters state ** + ** EMM-DEREGISTERED. ** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ -static void* _emm_attach_t3450_handler(void* args) +static void *_emm_attach_t3450_handler(void *args) { LOG_FUNC_IN; int rc; - attach_data_t* data = (attach_data_t*)(args); + attach_data_t *data = (attach_data_t *)(args); /* Increment the retransmission counter */ data->retransmission_count += 1; LOG_TRACE(WARNING, "EMM-PROC - T3450 timer expired, retransmission " - "counter = %d", data->retransmission_count); + "counter = %d", data->retransmission_count); /* Get the UE's EMM context */ - emm_data_context_t* emm_ctx = NULL; + emm_data_context_t *emm_ctx = NULL; #if defined(EPC_BUILD) emm_ctx = emm_data_context_get(&_emm_data, data->ueid); @@ -1589,12 +1569,11 @@ static void* _emm_attach_t3450_handler(void* args) #endif if (data->retransmission_count < ATTACH_COUNTER_MAX) { - /* Send attach accept message to the UE */ - rc = _emm_attach_accept(emm_ctx, data); - } - else { - /* Abort the attach procedure */ - rc = _emm_attach_abort(data); + /* Send attach accept message to the UE */ + rc = _emm_attach_accept(emm_ctx, data); + } else { + /* Abort the attach procedure */ + rc = _emm_attach_abort(data); } LOG_FUNC_RETURN(NULL); @@ -1602,65 +1581,78 @@ static void* _emm_attach_t3450_handler(void* args) /* * -------------------------------------------------------------------------- - * Abnormal cases in the MME + * Abnormal cases in the MME * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _emm_attach_release() ** + ** Name: _emm_attach_release() ** ** ** ** Description: Releases the UE context data. ** ** ** - ** Inputs: args: Data to be released ** - ** Others: None ** + ** Inputs: args: Data to be released ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ -static int _emm_attach_release(void* args) +static int _emm_attach_release(void *args) { LOG_FUNC_IN; int rc = RETURNerror; - emm_data_context_t* emm_ctx = (emm_data_context_t*)(args); + emm_data_context_t *emm_ctx = (emm_data_context_t *)(args); - if (emm_ctx) - { - LOG_TRACE(WARNING, "EMM-PROC - Release UE context data (ueid=%u)", - emm_ctx->ueid); - - unsigned int ueid = emm_ctx->ueid; - - if (emm_ctx->guti) free(emm_ctx->guti); - if (emm_ctx->imsi) free(emm_ctx->imsi); - if (emm_ctx->imei) free(emm_ctx->imei); - if (emm_ctx->esm_msg.length > 0) free(emm_ctx->esm_msg.value); - /* Release NAS security context */ - if (emm_ctx->security) { - emm_security_context_t* security = emm_ctx->security; - if (security->kasme.value) free(security->kasme.value); - if (security->knas_enc.value) free(security->knas_enc.value); - if (security->knas_int.value) free(security->knas_int.value); - free(emm_ctx->security); - } - /* Release the EMM context */ + if (emm_ctx) { + LOG_TRACE(WARNING, "EMM-PROC - Release UE context data (ueid=%u)", + emm_ctx->ueid); + + unsigned int ueid = emm_ctx->ueid; + + if (emm_ctx->guti) { + free(emm_ctx->guti); + } + if (emm_ctx->imsi) { + free(emm_ctx->imsi); + } + if (emm_ctx->imei) { + free(emm_ctx->imei); + } + if (emm_ctx->esm_msg.length > 0) { + free(emm_ctx->esm_msg.value); + } + /* Release NAS security context */ + if (emm_ctx->security) { + emm_security_context_t *security = emm_ctx->security; + if (security->kasme.value) { + free(security->kasme.value); + } + if (security->knas_enc.value) { + free(security->knas_enc.value); + } + if (security->knas_int.value) { + free(security->knas_int.value); + } + free(emm_ctx->security); + } + /* Release the EMM context */ #if defined(EPC_BUILD) emm_data_context_remove(&_emm_data, emm_ctx); #else - free(_emm_data.ctx[ueid]); - _emm_data.ctx[ueid] = NULL; + free(_emm_data.ctx[ueid]); + _emm_data.ctx[ueid] = NULL; #endif - /* - * Notify EMM that the attach procedure is aborted - */ - emm_sap_t emm_sap; - emm_sap.primitive = EMMREG_PROC_ABORT; - emm_sap.u.emm_reg.ueid = ueid; - rc = emm_sap_send(&emm_sap); + /* + * Notify EMM that the attach procedure is aborted + */ + emm_sap_t emm_sap; + emm_sap.primitive = EMMREG_PROC_ABORT; + emm_sap.u.emm_reg.ueid = ueid; + rc = emm_sap_send(&emm_sap); } LOG_FUNC_RETURN(rc); @@ -1668,68 +1660,67 @@ static int _emm_attach_release(void* args) /**************************************************************************** ** ** - ** Name: _emm_attach_reject() ** + ** Name: _emm_attach_reject() ** ** ** ** Description: Performs the attach procedure not accepted by the network.** ** ** ** 3GPP TS 24.301, section 5.5.1.2.5 ** - ** If the attach request cannot be accepted by the network, ** - ** the MME shall send an ATTACH REJECT message to the UE in- ** - ** including an appropriate EMM cause value. ** + ** If the attach request cannot be accepted by the network, ** + ** the MME shall send an ATTACH REJECT message to the UE in- ** + ** including an appropriate EMM cause value. ** ** ** - ** Inputs: args: UE context data ** - ** Others: None ** + ** Inputs: args: UE context data ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -static int _emm_attach_reject(void* args) +static int _emm_attach_reject(void *args) { LOG_FUNC_IN; int rc = RETURNerror; - emm_data_context_t* emm_ctx = (emm_data_context_t*)(args); + emm_data_context_t *emm_ctx = (emm_data_context_t *)(args); - if (emm_ctx) - { - emm_sap_t emm_sap; - LOG_TRACE(WARNING, "EMM-PROC - EMM attach procedure not accepted " - "by the network (ueid=%08x, cause=%d)", - emm_ctx->ueid, emm_ctx->emm_cause); - /* - * Notify EMM-AS SAP that Attach Reject message has to be sent - * onto the network - */ - emm_sap.primitive = EMMAS_ESTABLISH_REJ; - emm_sap.u.emm_as.u.establish.ueid = emm_ctx->ueid; - emm_sap.u.emm_as.u.establish.UEid.guti = NULL; - if (emm_ctx->emm_cause == EMM_CAUSE_SUCCESS) { - emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; - } - emm_sap.u.emm_as.u.establish.emm_cause = emm_ctx->emm_cause; - emm_sap.u.emm_as.u.establish.NASinfo = EMM_AS_NAS_INFO_ATTACH; - if (emm_ctx->emm_cause != EMM_CAUSE_ESM_FAILURE) { - emm_sap.u.emm_as.u.establish.NASmsg.length = 0; - emm_sap.u.emm_as.u.establish.NASmsg.value = NULL; - } else if (emm_ctx->esm_msg.length > 0) { - emm_sap.u.emm_as.u.establish.NASmsg = emm_ctx->esm_msg; - } else { - LOG_TRACE(ERROR, "EMM-PROC - ESM message is missing"); - LOG_FUNC_RETURN(RETURNerror); - } - /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_sap.u.emm_as.u.establish.sctx, - emm_ctx->security, FALSE, TRUE); - rc = emm_sap_send(&emm_sap); - - /* Release the UE context, even if the network failed to send the - * ATTACH REJECT message */ - if (emm_ctx->is_dynamic) { - rc = _emm_attach_release(emm_ctx); - } + if (emm_ctx) { + emm_sap_t emm_sap; + LOG_TRACE(WARNING, "EMM-PROC - EMM attach procedure not accepted " + "by the network (ueid=%08x, cause=%d)", + emm_ctx->ueid, emm_ctx->emm_cause); + /* + * Notify EMM-AS SAP that Attach Reject message has to be sent + * onto the network + */ + emm_sap.primitive = EMMAS_ESTABLISH_REJ; + emm_sap.u.emm_as.u.establish.ueid = emm_ctx->ueid; + emm_sap.u.emm_as.u.establish.UEid.guti = NULL; + if (emm_ctx->emm_cause == EMM_CAUSE_SUCCESS) { + emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; + } + emm_sap.u.emm_as.u.establish.emm_cause = emm_ctx->emm_cause; + emm_sap.u.emm_as.u.establish.NASinfo = EMM_AS_NAS_INFO_ATTACH; + if (emm_ctx->emm_cause != EMM_CAUSE_ESM_FAILURE) { + emm_sap.u.emm_as.u.establish.NASmsg.length = 0; + emm_sap.u.emm_as.u.establish.NASmsg.value = NULL; + } else if (emm_ctx->esm_msg.length > 0) { + emm_sap.u.emm_as.u.establish.NASmsg = emm_ctx->esm_msg; + } else { + LOG_TRACE(ERROR, "EMM-PROC - ESM message is missing"); + LOG_FUNC_RETURN(RETURNerror); + } + /* Setup EPS NAS security data */ + emm_as_set_security_data(&emm_sap.u.emm_as.u.establish.sctx, + emm_ctx->security, FALSE, TRUE); + rc = emm_sap_send(&emm_sap); + + /* Release the UE context, even if the network failed to send the + * ATTACH REJECT message */ + if (emm_ctx->is_dynamic) { + rc = _emm_attach_release(emm_ctx); + } } LOG_FUNC_RETURN(rc); @@ -1737,62 +1728,61 @@ static int _emm_attach_reject(void* args) /**************************************************************************** ** ** - ** Name: _emm_attach_abort() ** + ** Name: _emm_attach_abort() ** ** ** ** Description: Aborts the attach procedure ** ** ** - ** Inputs: args: Attach procedure data to be released ** - ** Others: None ** + ** Inputs: args: Attach procedure data to be released ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3450 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3450 ** ** ** ***************************************************************************/ -static int _emm_attach_abort(void* args) +static int _emm_attach_abort(void *args) { LOG_FUNC_IN; int rc = RETURNerror; - attach_data_t* data = (attach_data_t*)(args); + attach_data_t *data = (attach_data_t *)(args); - if (data) - { - unsigned int ueid = data->ueid; - - LOG_TRACE(WARNING, "EMM-PROC - Abort the attach procedure (ueid=%u)", - ueid); - - /* Stop timer T3450 */ - if (T3450.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3450 (%d)", T3450.id); - T3450.id = nas_timer_stop(T3450.id); - } - /* Release retransmission timer parameters */ - if (data->esm_msg.length > 0) { - free(data->esm_msg.value); - } - free(data); - - /* - * Notify ESM that the network locally refused PDN connectivity - * to the UE - */ - esm_sap_t esm_sap; - esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; - esm_sap.ueid = ueid; - esm_sap.recv = NULL; - rc = esm_sap_send(&esm_sap); - if (rc != RETURNerror) { - /* - * Notify EMM that EPS attach procedure failed - */ - emm_sap_t emm_sap; - emm_sap.primitive = EMMREG_ATTACH_REJ; - emm_sap.u.emm_reg.ueid = ueid; - rc = emm_sap_send(&emm_sap); - if (rc != RETURNerror) { + if (data) { + unsigned int ueid = data->ueid; + + LOG_TRACE(WARNING, "EMM-PROC - Abort the attach procedure (ueid=%u)", + ueid); + + /* Stop timer T3450 */ + if (T3450.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3450 (%d)", T3450.id); + T3450.id = nas_timer_stop(T3450.id); + } + /* Release retransmission timer parameters */ + if (data->esm_msg.length > 0) { + free(data->esm_msg.value); + } + free(data); + + /* + * Notify ESM that the network locally refused PDN connectivity + * to the UE + */ + esm_sap_t esm_sap; + esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; + esm_sap.ueid = ueid; + esm_sap.recv = NULL; + rc = esm_sap_send(&esm_sap); + if (rc != RETURNerror) { + /* + * Notify EMM that EPS attach procedure failed + */ + emm_sap_t emm_sap; + emm_sap.primitive = EMMREG_ATTACH_REJ; + emm_sap.u.emm_reg.ueid = ueid; + rc = emm_sap_send(&emm_sap); + if (rc != RETURNerror) { struct emm_data_context_s *ctx = NULL; #if defined(EPC_BUILD) @@ -1801,10 +1791,10 @@ static int _emm_attach_abort(void* args) ctx = _emm_data.ctx[ueid]; #endif - /* Release the UE context */ + /* Release the UE context */ rc = _emm_attach_release(ctx); - } - } + } + } } LOG_FUNC_RETURN (rc); @@ -1812,95 +1802,92 @@ static int _emm_attach_abort(void* args) /* * -------------------------------------------------------------------------- - * Functions that may initiate EMM common procedures + * Functions that may initiate EMM common procedures * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _emm_attach_identify() ** + ** Name: _emm_attach_identify() ** ** ** ** Description: Performs UE's identification. May initiates identifica- ** - ** tion, authentication and security mode control EMM common ** - ** procedures. ** + ** tion, authentication and security mode control EMM common ** + ** procedures. ** ** ** - ** Inputs: args: Identification argument parameters ** - ** Others: None ** + ** Inputs: args: Identification argument parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ -static int _emm_attach_identify(void* args) +static int _emm_attach_identify(void *args) { LOG_FUNC_IN; int rc = RETURNerror; - emm_data_context_t* emm_ctx = (emm_data_context_t*)(args); + emm_data_context_t *emm_ctx = (emm_data_context_t *)(args); int guti_reallocation = FALSE; LOG_TRACE(INFO, "EMM-PROC - Identify incoming UE (ueid=0x%08x) using %s", - emm_ctx->ueid, (emm_ctx->imsi)? "IMSI" : (emm_ctx->guti)? "GUTI" : - (emm_ctx->imei)? "IMEI" : "none"); + emm_ctx->ueid, (emm_ctx->imsi)? "IMSI" : (emm_ctx->guti)? "GUTI" : + (emm_ctx->imei)? "IMEI" : "none"); /* * UE's identification * ------------------- */ if (emm_ctx->imsi) { - /* The UE identifies itself using an IMSI */ - rc = mme_api_identify_imsi(emm_ctx->imsi, &emm_ctx->vector); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-PROC - " - "Failed to identify the UE using provided IMSI"); - emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; - } - guti_reallocation = TRUE; - } - else if (emm_ctx->guti) { - /* The UE identifies itself using a GUTI */ - rc = mme_api_identify_guti(emm_ctx->guti, &emm_ctx->vector); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-PROC - Failed to identify the UE using " - "provided GUTI (tmsi=%u)", emm_ctx->guti->m_tmsi); - /* 3GPP TS 24.401, Figure 5.3.2.1-1, point 4 - * The UE was attempting to attach to the network using a GUTI - * that is not known by the network; the MME shall initiate an - * identification procedure to retrieve the IMSI from the UE. - */ - rc = emm_proc_identification(emm_ctx->ueid, + /* The UE identifies itself using an IMSI */ + rc = mme_api_identify_imsi(emm_ctx->imsi, &emm_ctx->vector); + if (rc != RETURNok) { + LOG_TRACE(WARNING, "EMM-PROC - " + "Failed to identify the UE using provided IMSI"); + emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; + } + guti_reallocation = TRUE; + } else if (emm_ctx->guti) { + /* The UE identifies itself using a GUTI */ + rc = mme_api_identify_guti(emm_ctx->guti, &emm_ctx->vector); + if (rc != RETURNok) { + LOG_TRACE(WARNING, "EMM-PROC - Failed to identify the UE using " + "provided GUTI (tmsi=%u)", emm_ctx->guti->m_tmsi); + /* 3GPP TS 24.401, Figure 5.3.2.1-1, point 4 + * The UE was attempting to attach to the network using a GUTI + * that is not known by the network; the MME shall initiate an + * identification procedure to retrieve the IMSI from the UE. + */ + rc = emm_proc_identification(emm_ctx->ueid, emm_ctx, EMM_IDENT_TYPE_IMSI, - _emm_attach_identify, - _emm_attach_release, - _emm_attach_release); - if (rc != RETURNok) { - /* Failed to initiate the identification procedure */ - LOG_TRACE(WARNING, "EMM-PROC - " - "Failed to initiate identification procedure"); - emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; - /* Do not accept the UE to attach to the network */ - rc = _emm_attach_reject(emm_ctx); - } - /* Relevant callback will be executed when identification - * procedure completes */ - LOG_FUNC_RETURN(rc); - } - } - else if ( (emm_ctx->imei) && (emm_ctx->is_emergency) ) { - /* The UE is attempting to attach to the network for emergency - * services using an IMEI */ - rc = mme_api_identify_imei(emm_ctx->imei, &emm_ctx->vector); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-PROC - " - "Failed to identify the UE using provided IMEI"); - emm_ctx->emm_cause = EMM_CAUSE_IMEI_NOT_ACCEPTED; - } - } - else { - LOG_TRACE(WARNING, "EMM-PROC - UE's identity is not available"); - emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; + _emm_attach_identify, + _emm_attach_release, + _emm_attach_release); + if (rc != RETURNok) { + /* Failed to initiate the identification procedure */ + LOG_TRACE(WARNING, "EMM-PROC - " + "Failed to initiate identification procedure"); + emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; + /* Do not accept the UE to attach to the network */ + rc = _emm_attach_reject(emm_ctx); + } + /* Relevant callback will be executed when identification + * procedure completes */ + LOG_FUNC_RETURN(rc); + } + } else if ( (emm_ctx->imei) && (emm_ctx->is_emergency) ) { + /* The UE is attempting to attach to the network for emergency + * services using an IMEI */ + rc = mme_api_identify_imei(emm_ctx->imei, &emm_ctx->vector); + if (rc != RETURNok) { + LOG_TRACE(WARNING, "EMM-PROC - " + "Failed to identify the UE using provided IMEI"); + emm_ctx->emm_cause = EMM_CAUSE_IMEI_NOT_ACCEPTED; + } + } else { + LOG_TRACE(WARNING, "EMM-PROC - UE's identity is not available"); + emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; } /* @@ -1908,27 +1895,26 @@ static int _emm_attach_identify(void* args) * ----------------- */ if ( (rc != RETURNerror) && guti_reallocation ) { - /* Release the old GUTI */ - if (emm_ctx->old_guti) { - free(emm_ctx->old_guti); - } - /* Save the GUTI previously used by the UE to identify itself */ - emm_ctx->old_guti = emm_ctx->guti; - /* Allocate a new GUTI */ - emm_ctx->guti = (GUTI_t*)malloc(sizeof(GUTI_t)); - /* Request the MME to assign a GUTI to the UE */ - rc = mme_api_new_guti(emm_ctx->imsi, emm_ctx->guti, - &emm_ctx->tac, &emm_ctx->n_tacs); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-PROC - Failed to assign new GUTI"); - emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; - } - else { - LOG_TRACE(WARNING, "EMM-PROC - New GUTI assigned to the UE " - "(tmsi=%u)", emm_ctx->guti->m_tmsi); - /* Update the GUTI indicator as new */ - emm_ctx->guti_is_new = TRUE; - } + /* Release the old GUTI */ + if (emm_ctx->old_guti) { + free(emm_ctx->old_guti); + } + /* Save the GUTI previously used by the UE to identify itself */ + emm_ctx->old_guti = emm_ctx->guti; + /* Allocate a new GUTI */ + emm_ctx->guti = (GUTI_t *)malloc(sizeof(GUTI_t)); + /* Request the MME to assign a GUTI to the UE */ + rc = mme_api_new_guti(emm_ctx->imsi, emm_ctx->guti, + &emm_ctx->tac, &emm_ctx->n_tacs); + if (rc != RETURNok) { + LOG_TRACE(WARNING, "EMM-PROC - Failed to assign new GUTI"); + emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; + } else { + LOG_TRACE(WARNING, "EMM-PROC - New GUTI assigned to the UE " + "(tmsi=%u)", emm_ctx->guti->m_tmsi); + /* Update the GUTI indicator as new */ + emm_ctx->guti_is_new = TRUE; + } } /* @@ -1936,105 +1922,102 @@ static int _emm_attach_identify(void* args) * ------------------- */ if (rc != RETURNerror) { - if (emm_ctx->security) { - /* A security context exists for the UE in the network; - * proceed with the attach procedure. - */ - rc = _emm_attach(emm_ctx); - } - else if ( (emm_ctx->is_emergency) && - (_emm_data.conf.features & MME_API_UNAUTHENTICATED_IMSI) ) { - /* 3GPP TS 24.301, section 5.5.1.2.3 - * 3GPP TS 24.401, Figure 5.3.2.1-1, point 5a - * MME configured to support Emergency Attach for unauthenticated - * IMSIs may choose to skip the authentication procedure even if - * no EPS security context is available and proceed directly to the - * execution of the security mode control procedure. - */ - rc = _emm_attach_security(emm_ctx); - } - else { - /* 3GPP TS 24.401, Figure 5.3.2.1-1, point 5a - * No EMM context exists for the UE in the network; authentication - * and NAS security setup to activate integrity protection and NAS - * ciphering are mandatory. - */ - auth_vector_t* auth = &emm_ctx->vector; - const OctetString loc_rand = {AUTH_RAND_SIZE, (uint8_t*)auth->rand}; - const OctetString autn = {AUTH_AUTN_SIZE, (uint8_t*)auth->autn}; - rc = emm_proc_authentication(emm_ctx->ueid, 0, // TODO: eksi != 0 + if (emm_ctx->security) { + /* A security context exists for the UE in the network; + * proceed with the attach procedure. + */ + rc = _emm_attach(emm_ctx); + } else if ( (emm_ctx->is_emergency) && + (_emm_data.conf.features & MME_API_UNAUTHENTICATED_IMSI) ) { + /* 3GPP TS 24.301, section 5.5.1.2.3 + * 3GPP TS 24.401, Figure 5.3.2.1-1, point 5a + * MME configured to support Emergency Attach for unauthenticated + * IMSIs may choose to skip the authentication procedure even if + * no EPS security context is available and proceed directly to the + * execution of the security mode control procedure. + */ + rc = _emm_attach_security(emm_ctx); + } else { + /* 3GPP TS 24.401, Figure 5.3.2.1-1, point 5a + * No EMM context exists for the UE in the network; authentication + * and NAS security setup to activate integrity protection and NAS + * ciphering are mandatory. + */ + auth_vector_t *auth = &emm_ctx->vector; + const OctetString loc_rand = {AUTH_RAND_SIZE, (uint8_t *)auth->rand}; + const OctetString autn = {AUTH_AUTN_SIZE, (uint8_t *)auth->autn}; + rc = emm_proc_authentication(emm_ctx->ueid, 0, // TODO: eksi != 0 &loc_rand, &autn, - _emm_attach_security, - _emm_attach_release, - _emm_attach_release); - if (rc != RETURNok) { - /* Failed to initiate the authentication procedure */ - LOG_TRACE(WARNING, "EMM-PROC - " - "Failed to initiate authentication procedure"); - emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; - } - } - } + _emm_attach_security, + _emm_attach_release, + _emm_attach_release); + if (rc != RETURNok) { + /* Failed to initiate the authentication procedure */ + LOG_TRACE(WARNING, "EMM-PROC - " + "Failed to initiate authentication procedure"); + emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; + } + } + } if (rc != RETURNok) { - /* Do not accept the UE to attach to the network */ - rc = _emm_attach_reject(emm_ctx); + /* Do not accept the UE to attach to the network */ + rc = _emm_attach_reject(emm_ctx); } LOG_FUNC_RETURN (rc); } /**************************************************************************** ** ** - ** Name: _emm_attach_security() ** + ** Name: _emm_attach_security() ** ** ** ** Description: Initiates security mode control EMM common procedure. ** ** ** - ** Inputs: args: security argument parameters ** - ** Others: None ** + ** Inputs: args: security argument parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ -static int _emm_attach_security(void* args) +static int _emm_attach_security(void *args) { LOG_FUNC_IN; int rc; - emm_data_context_t* emm_ctx = (emm_data_context_t*)(args); + emm_data_context_t *emm_ctx = (emm_data_context_t *)(args); LOG_TRACE(INFO, "EMM-PROC - Setup NAS security (ueid=%u)", emm_ctx->ueid); /* Create new NAS security context */ if (emm_ctx->security == NULL) { - emm_ctx->security = - (emm_security_context_t*)malloc(sizeof(emm_security_context_t)); + emm_ctx->security = + (emm_security_context_t *)malloc(sizeof(emm_security_context_t)); } if (emm_ctx->security) { - memset(emm_ctx->security, 0, sizeof(emm_security_context_t)); - emm_ctx->security->type = EMM_KSI_NOT_AVAILABLE; - } - else { - LOG_TRACE(WARNING, "EMM-PROC - Failed to create security context"); - emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; - /* Do not accept the UE to attach to the network */ - rc = _emm_attach_reject(emm_ctx); - LOG_FUNC_RETURN(rc); + memset(emm_ctx->security, 0, sizeof(emm_security_context_t)); + emm_ctx->security->type = EMM_KSI_NOT_AVAILABLE; + } else { + LOG_TRACE(WARNING, "EMM-PROC - Failed to create security context"); + emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; + /* Do not accept the UE to attach to the network */ + rc = _emm_attach_reject(emm_ctx); + LOG_FUNC_RETURN(rc); } /* Initialize the security mode control procedure */ rc = emm_proc_security_mode_control(emm_ctx->ueid, 0, // TODO: eksi != 0 - emm_ctx->eea, emm_ctx->eia, - _emm_attach, _emm_attach_release, - _emm_attach_release); + emm_ctx->eea, emm_ctx->eia, + _emm_attach, _emm_attach_release, + _emm_attach_release); if (rc != RETURNok) { - /* Failed to initiate the security mode control procedure */ - LOG_TRACE(WARNING, "EMM-PROC - " - "Failed to initiate security mode control procedure"); - emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; - /* Do not accept the UE to attach to the network */ - rc = _emm_attach_reject(emm_ctx); + /* Failed to initiate the security mode control procedure */ + LOG_TRACE(WARNING, "EMM-PROC - " + "Failed to initiate security mode control procedure"); + emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; + /* Do not accept the UE to attach to the network */ + rc = _emm_attach_reject(emm_ctx); } LOG_FUNC_RETURN (rc); @@ -2042,38 +2025,38 @@ static int _emm_attach_security(void* args) /* * -------------------------------------------------------------------------- - * MME specific local functions + * MME specific local functions * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _emm_attach() ** + ** Name: _emm_attach() ** ** ** ** Description: Performs the attach signalling procedure while a context ** - ** exists for the incoming UE in the network. ** + ** exists for the incoming UE in the network. ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.4 ** - ** Upon receiving the ATTACH REQUEST message, the MME shall ** - ** send an ATTACH ACCEPT message to the UE and start timer ** - ** T3450. ** + ** Upon receiving the ATTACH REQUEST message, the MME shall ** + ** send an ATTACH ACCEPT message to the UE and start timer ** + ** T3450. ** ** ** - ** Inputs: args: attach argument parameters ** - ** Others: None ** + ** Inputs: args: attach argument parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ -static int _emm_attach(void* args) +static int _emm_attach(void *args) { LOG_FUNC_IN; esm_sap_t esm_sap; int rc; - emm_data_context_t* emm_ctx = (emm_data_context_t*)(args); + emm_data_context_t *emm_ctx = (emm_data_context_t *)(args); LOG_TRACE(INFO, "EMM-PROC - Attach UE (ueid=%u)", emm_ctx->ueid); @@ -2093,90 +2076,88 @@ static int _emm_attach(void* args) rc = esm_sap_send(&esm_sap); if ( (rc != RETURNerror) && (esm_sap.err == ESM_SAP_SUCCESS) ) { - /* - * The attach request is accepted by the network - */ - - /* Delete the stored UE radio capability information, if any */ - /* Store the UE network capability */ - /* Assign the TAI list the UE is registered to */ - - /* Allocate parameters of the retransmission timer callback */ - attach_data_t* data = (attach_data_t*)malloc(sizeof(attach_data_t)); - - if (data != NULL) { - /* Setup ongoing EMM procedure callback functions */ - rc = emm_proc_common_initialize(emm_ctx->ueid, NULL, NULL, NULL, - _emm_attach_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 = emm_ctx->ueid; - /* Reset the retransmission counter */ - data->retransmission_count = 0; - /* Setup the ESM message container */ - data->esm_msg.value = (uint8_t*)malloc(esm_sap.send.length); - if (data->esm_msg.value) { - data->esm_msg.length = esm_sap.send.length; - memcpy(data->esm_msg.value, esm_sap.send.value, - esm_sap.send.length); - } else { - data->esm_msg.length = 0; - } - /* Send attach accept message to the UE */ - rc = _emm_attach_accept(emm_ctx, data); - if (rc != RETURNerror) { - if (emm_ctx->guti_is_new && emm_ctx->old_guti) { - /* Implicit GUTI reallocation; - * Notify EMM that common procedure has been initiated - */ - emm_sap_t emm_sap; - emm_sap.primitive = EMMREG_COMMON_PROC_REQ; - emm_sap.u.emm_reg.ueid = data->ueid; - rc = emm_sap_send(&emm_sap); - } - } - } - } - else if (esm_sap.err != ESM_SAP_DISCARDED) { - /* - * The attach procedure failed due to an ESM procedure failure - */ - emm_ctx->emm_cause = EMM_CAUSE_ESM_FAILURE; - /* Setup the ESM message container to include PDN Connectivity Reject - * message within the Attach Reject message */ - if (emm_ctx->esm_msg.length > 0) { - free(emm_ctx->esm_msg.value); - } - emm_ctx->esm_msg.value = (uint8_t*)malloc(esm_sap.send.length); - if (emm_ctx->esm_msg.value) { - emm_ctx->esm_msg.length = esm_sap.send.length; - memcpy(emm_ctx->esm_msg.value, esm_sap.send.value, - esm_sap.send.length); - /* Send Attach Reject message */ - rc = _emm_attach_reject(emm_ctx); - } else { - emm_ctx->esm_msg.length = 0; - } - } - else { - /* - * ESM procedure failed and, received message has been discarded or - * Status message has been returned; ignore ESM procedure failure - */ - rc = RETURNok; + /* + * The attach request is accepted by the network + */ + + /* Delete the stored UE radio capability information, if any */ + /* Store the UE network capability */ + /* Assign the TAI list the UE is registered to */ + + /* Allocate parameters of the retransmission timer callback */ + attach_data_t *data = (attach_data_t *)malloc(sizeof(attach_data_t)); + + if (data != NULL) { + /* Setup ongoing EMM procedure callback functions */ + rc = emm_proc_common_initialize(emm_ctx->ueid, NULL, NULL, NULL, + _emm_attach_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 = emm_ctx->ueid; + /* Reset the retransmission counter */ + data->retransmission_count = 0; + /* Setup the ESM message container */ + data->esm_msg.value = (uint8_t *)malloc(esm_sap.send.length); + if (data->esm_msg.value) { + data->esm_msg.length = esm_sap.send.length; + memcpy(data->esm_msg.value, esm_sap.send.value, + esm_sap.send.length); + } else { + data->esm_msg.length = 0; + } + /* Send attach accept message to the UE */ + rc = _emm_attach_accept(emm_ctx, data); + if (rc != RETURNerror) { + if (emm_ctx->guti_is_new && emm_ctx->old_guti) { + /* Implicit GUTI reallocation; + * Notify EMM that common procedure has been initiated + */ + emm_sap_t emm_sap; + emm_sap.primitive = EMMREG_COMMON_PROC_REQ; + emm_sap.u.emm_reg.ueid = data->ueid; + rc = emm_sap_send(&emm_sap); + } + } + } + } else if (esm_sap.err != ESM_SAP_DISCARDED) { + /* + * The attach procedure failed due to an ESM procedure failure + */ + emm_ctx->emm_cause = EMM_CAUSE_ESM_FAILURE; + /* Setup the ESM message container to include PDN Connectivity Reject + * message within the Attach Reject message */ + if (emm_ctx->esm_msg.length > 0) { + free(emm_ctx->esm_msg.value); + } + emm_ctx->esm_msg.value = (uint8_t *)malloc(esm_sap.send.length); + if (emm_ctx->esm_msg.value) { + emm_ctx->esm_msg.length = esm_sap.send.length; + memcpy(emm_ctx->esm_msg.value, esm_sap.send.value, + esm_sap.send.length); + /* Send Attach Reject message */ + rc = _emm_attach_reject(emm_ctx); + } else { + emm_ctx->esm_msg.length = 0; + } + } else { + /* + * ESM procedure failed and, received message has been discarded or + * Status message has been returned; ignore ESM procedure failure + */ + rc = RETURNok; } if (rc != RETURNok) { - /* The attach procedure failed */ - LOG_TRACE(WARNING, "EMM-PROC - Failed to respond to Attach Request"); - emm_ctx->emm_cause = EMM_CAUSE_PROTOCOL_ERROR; - /* Do not accept the UE to attach to the network */ - rc = _emm_attach_reject(emm_ctx); + /* The attach procedure failed */ + LOG_TRACE(WARNING, "EMM-PROC - Failed to respond to Attach Request"); + emm_ctx->emm_cause = EMM_CAUSE_PROTOCOL_ERROR; + /* Do not accept the UE to attach to the network */ + rc = _emm_attach_reject(emm_ctx); } LOG_FUNC_RETURN (rc); @@ -2184,19 +2165,19 @@ static int _emm_attach(void* args) /**************************************************************************** ** ** - ** Name: _emm_attach_accept() ** + ** Name: _emm_attach_accept() ** ** ** ** Description: Sends ATTACH ACCEPT message and start timer T3450 ** ** ** - ** Inputs: data: Attach accept retransmission data ** - ** Others: None ** + ** Inputs: data: Attach accept retransmission data ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3450 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3450 ** ** ** ***************************************************************************/ -static int _emm_attach_accept(emm_data_context_t* emm_ctx, attach_data_t* data) +static int _emm_attach_accept(emm_data_context_t *emm_ctx, attach_data_t *data) { LOG_FUNC_IN; @@ -2210,35 +2191,35 @@ static int _emm_attach_accept(emm_data_context_t* emm_ctx, attach_data_t* data) emm_sap.primitive = EMMAS_ESTABLISH_CNF; emm_sap.u.emm_as.u.establish.ueid = emm_ctx->ueid; if (emm_ctx->guti_is_new && emm_ctx->old_guti) { - /* Implicit GUTI reallocation; - * include the new assigned GUTI in the Attach Accept message */ - emm_sap.u.emm_as.u.establish.UEid.guti = emm_ctx->old_guti; - emm_sap.u.emm_as.u.establish.new_guti = emm_ctx->guti; + /* Implicit GUTI reallocation; + * include the new assigned GUTI in the Attach Accept message */ + emm_sap.u.emm_as.u.establish.UEid.guti = emm_ctx->old_guti; + emm_sap.u.emm_as.u.establish.new_guti = emm_ctx->guti; } else { - emm_sap.u.emm_as.u.establish.UEid.guti = emm_ctx->guti; - emm_sap.u.emm_as.u.establish.new_guti = NULL; + emm_sap.u.emm_as.u.establish.UEid.guti = emm_ctx->guti; + emm_sap.u.emm_as.u.establish.new_guti = NULL; } emm_sap.u.emm_as.u.establish.n_tacs = emm_ctx->n_tacs; emm_sap.u.emm_as.u.establish.tac = emm_ctx->tac; emm_sap.u.emm_as.u.establish.NASinfo = EMM_AS_NAS_INFO_ATTACH; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.establish.sctx, - emm_ctx->security, FALSE, TRUE); + emm_ctx->security, FALSE, TRUE); /* Get the activate default EPS bearer context request message to * transfer within the ESM container of the attach accept message */ emm_sap.u.emm_as.u.establish.NASmsg = data->esm_msg; rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { - if (T3450.id != NAS_TIMER_INACTIVE_ID) { - /* Re-start T3450 timer */ - T3450.id = nas_timer_restart(T3450.id); - } else { - /* Start T3450 timer */ - T3450.id = nas_timer_start(T3450.sec, _emm_attach_t3450_handler, data); - } - LOG_TRACE(INFO,"EMM-PROC - Timer T3450 (%d) expires in %ld seconds", - T3450.id, T3450.sec); + if (T3450.id != NAS_TIMER_INACTIVE_ID) { + /* Re-start T3450 timer */ + T3450.id = nas_timer_restart(T3450.id); + } else { + /* Start T3450 timer */ + T3450.id = nas_timer_start(T3450.sec, _emm_attach_t3450_handler, data); + } + LOG_TRACE(INFO,"EMM-PROC - Timer T3450 (%d) expires in %ld seconds", + T3450.id, T3450.sec); } LOG_FUNC_RETURN (rc); @@ -2246,93 +2227,119 @@ static int _emm_attach_accept(emm_data_context_t* emm_ctx, attach_data_t* data) /**************************************************************************** ** ** - ** Name: _emm_attach_have_changed() ** + ** Name: _emm_attach_have_changed() ** ** ** ** Description: Check whether the given attach parameters differs from ** - ** those previously stored when the attach procedure has ** - ** been initiated. ** - ** ** - ** Inputs: ctx: EMM context of the UE in the network ** - ** type: Type of the requested attach ** - ** ksi: Security ket sey identifier ** - ** guti: The GUTI provided by the UE ** - ** imsi: The IMSI provided by the UE ** - ** imei: The IMEI provided by the UE ** - ** eea: Supported EPS encryption algorithms ** - ** eia: Supported EPS integrity algorithms ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: TRUE if at least one of the parameters ** - ** differs; FALSE otherwise. ** - ** Others: None ** + ** those previously stored when the attach procedure has ** + ** been initiated. ** + ** ** + ** Inputs: ctx: EMM context of the UE in the network ** + ** type: Type of the requested attach ** + ** ksi: Security ket sey identifier ** + ** guti: The GUTI provided by the UE ** + ** imsi: The IMSI provided by the UE ** + ** imei: The IMEI provided by the UE ** + ** eea: Supported EPS encryption algorithms ** + ** eia: Supported EPS integrity algorithms ** + ** Others: None ** + ** ** + ** Outputs: None ** + ** Return: TRUE if at least one of the parameters ** + ** differs; FALSE otherwise. ** + ** Others: None ** ** ** ***************************************************************************/ -static int _emm_attach_have_changed(const emm_data_context_t* ctx, - emm_proc_attach_type_t type, int ksi, - GUTI_t* guti, imsi_t* imsi, imei_t* imei, - int eea, int eia) +static int _emm_attach_have_changed(const emm_data_context_t *ctx, + emm_proc_attach_type_t type, int ksi, + GUTI_t *guti, imsi_t *imsi, imei_t *imei, + int eea, int eia) { /* Emergency bearer services indicator */ - if ( (type == EMM_ATTACH_TYPE_EMERGENCY) != ctx->is_emergency) - return (TRUE); + if ( (type == EMM_ATTACH_TYPE_EMERGENCY) != ctx->is_emergency) { + return (TRUE); + } /* Security key set identifier */ - if (ksi != ctx->ksi) return (TRUE); + if (ksi != ctx->ksi) { + return (TRUE); + } /* Supported EPS encryption algorithms */ - if (eea != ctx->eea) return (TRUE); + if (eea != ctx->eea) { + return (TRUE); + } /* Supported EPS integrity algorithms */ - if (eia != ctx->eia) return (TRUE); + if (eia != ctx->eia) { + return (TRUE); + } /* The GUTI if provided by the UE */ - if ( (guti) && (ctx->guti == NULL) ) return (TRUE); - if ( (guti == NULL) && (ctx->guti) ) return (TRUE); + if ( (guti) && (ctx->guti == NULL) ) { + return (TRUE); + } + if ( (guti == NULL) && (ctx->guti) ) { + return (TRUE); + } if ( (guti) && (ctx->guti) ) { - if (guti->m_tmsi != ctx->guti->m_tmsi) return (TRUE); - if ( memcmp(&guti->gummei, &ctx->guti->gummei, sizeof(gummei_t)) != 0 ) - return (TRUE); + if (guti->m_tmsi != ctx->guti->m_tmsi) { + return (TRUE); + } + if ( memcmp(&guti->gummei, &ctx->guti->gummei, sizeof(gummei_t)) != 0 ) { + return (TRUE); + } } /* The IMSI if provided by the UE */ - if ( (imsi) && (ctx->imsi == NULL) ) return (TRUE); - if ( (imsi == NULL) && (ctx->imsi) ) return (TRUE); + if ( (imsi) && (ctx->imsi == NULL) ) { + return (TRUE); + } + if ( (imsi == NULL) && (ctx->imsi) ) { + return (TRUE); + } if ( (imsi) && (ctx->imsi) ) { - if ( memcmp(imsi, ctx->imsi, sizeof(imsi_t)) != 0 ) return (TRUE); + if ( memcmp(imsi, ctx->imsi, sizeof(imsi_t)) != 0 ) { + return (TRUE); + } } /* The IMEI if provided by the UE */ - if ( (imei) && (ctx->imei == NULL) ) return (TRUE); - if ( (imei == NULL) && (ctx->imei) ) return (TRUE); + if ( (imei) && (ctx->imei == NULL) ) { + return (TRUE); + } + if ( (imei == NULL) && (ctx->imei) ) { + return (TRUE); + } if ( (imei) && (ctx->imei) ) { - if ( memcmp(imei, ctx->imei, sizeof(imei_t)) != 0 ) return (TRUE); + if ( memcmp(imei, ctx->imei, sizeof(imei_t)) != 0 ) { + return (TRUE); + } } return (FALSE); } /**************************************************************************** ** ** - ** Name: _emm_attach_update() ** + ** Name: _emm_attach_update() ** ** ** ** Description: Update the EMM context with the given attach procedure ** - ** parameters. ** - ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** type: Type of the requested attach ** - ** ksi: Security ket sey identifier ** - ** guti: The GUTI provided by the UE ** - ** imsi: The IMSI provided by the UE ** - ** imei: The IMEI provided by the UE ** - ** eea: Supported EPS encryption algorithms ** - ** eia: Supported EPS integrity algorithms ** - ** esm_msg: ESM message contained with the attach re- ** - ** quest ** - ** Others: None ** - ** ** - ** Outputs: ctx: EMM context of the UE in the network ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** parameters. ** + ** ** + ** Inputs: ueid: UE lower layer identifier ** + ** type: Type of the requested attach ** + ** ksi: Security ket sey identifier ** + ** guti: The GUTI provided by the UE ** + ** imsi: The IMSI provided by the UE ** + ** imei: The IMEI provided by the UE ** + ** eea: Supported EPS encryption algorithms ** + ** eia: Supported EPS integrity algorithms ** + ** esm_msg: ESM message contained with the attach re- ** + ** quest ** + ** Others: None ** + ** ** + ** Outputs: ctx: EMM context of the UE in the network ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -static int _emm_attach_update(emm_data_context_t* ctx, unsigned int ueid, - emm_proc_attach_type_t type, int ksi, - GUTI_t* guti, imsi_t* imsi, imei_t* imei, - int eea, int eia, const OctetString* esm_msg) +static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, + emm_proc_attach_type_t type, int ksi, + GUTI_t *guti, imsi_t *imsi, imei_t *imei, + int eea, int eia, const OctetString *esm_msg) { /* UE identifier */ ctx->ueid = ueid; @@ -2346,37 +2353,48 @@ static int _emm_attach_update(emm_data_context_t* ctx, unsigned int ueid, ctx->eia = eia; /* The GUTI if provided by the UE */ if (guti) { - if (ctx->guti == NULL) - ctx->guti = (GUTI_t*)malloc(sizeof(GUTI_t)); - if (ctx->guti != NULL) - memcpy(ctx->guti, guti, sizeof(GUTI_t)); - else return (RETURNerror); + if (ctx->guti == NULL) { + ctx->guti = (GUTI_t *)malloc(sizeof(GUTI_t)); + } + if (ctx->guti != NULL) { + memcpy(ctx->guti, guti, sizeof(GUTI_t)); + } else { + return (RETURNerror); + } } /* The IMSI if provided by the UE */ if (imsi) { - if (ctx->imsi == NULL) - ctx->imsi = (imsi_t*)malloc(sizeof(imsi_t)); - if (ctx->imsi != NULL) - memcpy(ctx->imsi, imsi, sizeof(imsi_t)); - else return (RETURNerror); + if (ctx->imsi == NULL) { + ctx->imsi = (imsi_t *)malloc(sizeof(imsi_t)); + } + if (ctx->imsi != NULL) { + memcpy(ctx->imsi, imsi, sizeof(imsi_t)); + } else { + return (RETURNerror); + } } /* The IMEI if provided by the UE */ if (imei) { - if (ctx->imei == NULL) - ctx->imei = (imei_t*)malloc(sizeof(imei_t)); - if (ctx->imei != NULL) - memcpy(ctx->imei, imei, sizeof(imei_t)); - else return (RETURNerror); + if (ctx->imei == NULL) { + ctx->imei = (imei_t *)malloc(sizeof(imei_t)); + } + if (ctx->imei != NULL) { + memcpy(ctx->imei, imei, sizeof(imei_t)); + } else { + return (RETURNerror); + } } /* The ESM message contained within the attach request */ if (esm_msg->length > 0) { - if (ctx->esm_msg.length == 0) { - ctx->esm_msg.value = (uint8_t*)malloc(esm_msg->length); - } - if (ctx->esm_msg.value != NULL) { - strncpy((char*)ctx->esm_msg.value, - (char*)esm_msg->value, esm_msg->length); - } else return (RETURNerror); + if (ctx->esm_msg.length == 0) { + ctx->esm_msg.value = (uint8_t *)malloc(esm_msg->length); + } + if (ctx->esm_msg.value != NULL) { + strncpy((char *)ctx->esm_msg.value, + (char *)esm_msg->value, esm_msg->length); + } else { + return (RETURNerror); + } } ctx->esm_msg.length = esm_msg->length; /* Attachment indicator */ diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c b/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c index aebdcb916b3ad60eb1391992e4c34284ebd1cb3c..56c28cb23144f66a099be4b515da1e722c24ccff 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c @@ -1,34 +1,34 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source Authentication.c +Source Authentication.c -Version 0.1 +Version 0.1 -Date 2013/03/04 +Date 2013/03/04 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines the authentication EMM procedure executed by the - Non-Access Stratum. +Description Defines the authentication EMM procedure executed by the + Non-Access Stratum. - The purpose of the EPS authentication and key agreement (AKA) - procedure is to provide mutual authentication between the user - and the network and to agree on a key KASME. The procedure is - always initiated and controlled by the network. However, the - UE can reject the EPS authentication challenge sent by the - network. + The purpose of the EPS authentication and key agreement (AKA) + procedure is to provide mutual authentication between the user + and the network and to agree on a key KASME. The procedure is + always initiated and controlled by the network. However, the + UE can reject the EPS authentication challenge sent by the + network. - A partial native EPS security context is established in the - UE and the network when an EPS authentication is successfully - performed. The computed key material KASME is used as the - root for the EPS integrity protection and ciphering key - hierarchy. + A partial native EPS security context is established in the + UE and the network when an EPS authentication is successfully + performed. The computed key material KASME is used as the + root for the EPS integrity protection and ciphering key + hierarchy. *****************************************************************************/ @@ -45,8 +45,8 @@ Description Defines the authentication EMM procedure executed by the #include "usim_api.h" #endif -#include <stdlib.h> // malloc, free -#include <string.h> // memcpy, memcmp, memset +#include <stdlib.h> // malloc, free +#include <string.h> // memcpy, memcmp, memset /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -56,10 +56,10 @@ Description Defines the authentication EMM procedure executed by the /* * Retransmission timer handlers */ -extern void* _emm_attach_t3410_handler(void*); -extern void* _emm_service_t3417_handler(void*); -extern void* _emm_detach_t3421_handler(void*); -extern void* _emm_tau_t3430_handler(void*); +extern void *_emm_attach_t3410_handler(void *); +extern void *_emm_service_t3417_handler(void *); +extern void *_emm_detach_t3421_handler(void *); +extern void *_emm_tau_t3430_handler(void *); #endif // NAS_UE /****************************************************************************/ @@ -68,81 +68,84 @@ extern void* _emm_tau_t3430_handler(void*); /* * -------------------------------------------------------------------------- - * Internal data handled by the authentication procedure in the UE + * Internal data handled by the authentication procedure in the UE * -------------------------------------------------------------------------- */ #ifdef NAS_UE /* * Timer handlers */ -static void* _authentication_t3416_handler(void*); -static void* _authentication_t3418_handler(void*); -static void* _authentication_t3420_handler(void*); +static void *_authentication_t3416_handler(void *); +static void *_authentication_t3418_handler(void *); +static void *_authentication_t3420_handler(void *); /* * Internal data used for authentication procedure */ static struct { - uint8_t rand[AUTH_RAND_SIZE]; /* Random challenge number */ - uint8_t res[AUTH_RES_SIZE]; /* Authentication response */ - uint8_t ck[AUTH_CK_SIZE]; /* Ciphering key */ - uint8_t ik[AUTH_IK_SIZE]; /* Integrity key */ -#define AUTHENTICATION_T3410 0x01 -#define AUTHENTICATION_T3417 0x02 -#define AUTHENTICATION_T3421 0x04 -#define AUTHENTICATION_T3430 0x08 - unsigned char timers; /* Timer restart bitmap */ + uint8_t rand[AUTH_RAND_SIZE]; /* Random challenge number */ + uint8_t res[AUTH_RES_SIZE]; /* Authentication response */ + uint8_t ck[AUTH_CK_SIZE]; /* Ciphering key */ + uint8_t ik[AUTH_IK_SIZE]; /* Integrity key */ +#define AUTHENTICATION_T3410 0x01 +#define AUTHENTICATION_T3417 0x02 +#define AUTHENTICATION_T3421 0x04 +#define AUTHENTICATION_T3430 0x08 + unsigned char timers; /* Timer restart bitmap */ #define AUTHENTICATION_COUNTER_MAX 3 - unsigned char mac_count:2; /* MAC failure counter (#20) */ - unsigned char umts_count:2; /* UMTS challenge failure counter (#26) */ - unsigned char sync_count:2; /* Sync failure counter (#21) */ + unsigned char mac_count:2; /* MAC failure counter (#20) */ + unsigned char umts_count:2; /* UMTS challenge failure counter (#26) */ + unsigned char sync_count:2; /* Sync failure counter (#21) */ } _authentication_data; /* * Abnormal case authentication procedure */ -static int _authentication_abnormal_cases_cde(int emm_cause, const OctetString* auts); +static int _authentication_abnormal_cases_cde(int emm_cause, + const OctetString *auts); static int _authentication_abnormal_case_f(void); static int _authentication_stop_timers(void); static int _authentication_start_timers(void); -static int _authentication_kasme(const OctetString* autn, const OctetString* ck, const OctetString* ik, const plmn_t* plmn, OctetString* kasme); +static int _authentication_kasme(const OctetString *autn, + const OctetString *ck, const OctetString *ik, const plmn_t *plmn, + OctetString *kasme); #endif // NAS_UE /* * -------------------------------------------------------------------------- - * Internal data handled by the authentication procedure in the MME + * Internal data handled by the authentication procedure in the MME * -------------------------------------------------------------------------- */ #ifdef NAS_MME /* * Timer handlers */ -static void* _authentication_t3460_handler(void*); +static void *_authentication_t3460_handler(void *); /* * Function executed whenever the ongoing EMM procedure that initiated * the authentication procedure is aborted or the maximum value of the * retransmission timer counter is exceed */ -static int _authentication_abort(void*); +static int _authentication_abort(void *); /* * Internal data used for authentication procedure */ typedef struct { - unsigned int ueid; /* UE identifier */ -#define AUTHENTICATION_COUNTER_MAX 5 - unsigned int retransmission_count; /* Retransmission counter */ - int ksi; /* NAS key set identifier */ - OctetString rand; /* Random challenge number */ - OctetString autn; /* Authentication token */ - int notify_failure; /* Indicates whether the authentication - * procedure failure shall be notified - * to the ongoing EMM procedure */ + unsigned int ueid; /* UE identifier */ +#define AUTHENTICATION_COUNTER_MAX 5 + unsigned int retransmission_count; /* Retransmission counter */ + int ksi; /* NAS key set identifier */ + OctetString rand; /* Random challenge number */ + OctetString autn; /* Authentication token */ + int notify_failure; /* Indicates whether the authentication + * procedure failure shall be notified + * to the ongoing EMM procedure */ } authentication_data_t; -static int _authentication_request(authentication_data_t* data); +static int _authentication_request(authentication_data_t *data); static int _authentication_reject(unsigned int ueid); #endif // NAS_MME @@ -152,40 +155,40 @@ static int _authentication_reject(unsigned int ueid); /* * -------------------------------------------------------------------------- - * Authentication procedure executed by the UE + * Authentication procedure executed by the UE * -------------------------------------------------------------------------- */ #ifdef NAS_UE /**************************************************************************** ** ** - ** Name: emm_proc_authentication_request() ** + ** Name: emm_proc_authentication_request() ** ** ** ** Description: Performs the MME requested authentication procedure. ** ** ** ** 3GPP TS 24.301, section 5.4.2.3 ** - ** Upon receiving the AUTHENTICATION REQUEST message, the UE ** - ** shall store the received RAND together with the RES re- ** - ** turned from the USIM in the volatile memory of the ME, to ** - ** avoid a synchronisation failure. The UE shall process the ** - ** authentication challenge data and respond with an AUTHEN- ** - ** TICATION RESPONSE message to the network. ** - ** ** - ** Inputs: native_ksi: TRUE if the security context is of type ** - ** native (for KSIASME) ** - ** ksi: The NAS ket sey identifier ** - ** rand: Authentication parameter RAND ** - ** autn: Authentication parameter AUTN ** - ** Others: _emm_data, _authentication_data ** - ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _authentication_data, T3416, ** - ** T3418, T3420 ** + ** Upon receiving the AUTHENTICATION REQUEST message, the UE ** + ** shall store the received RAND together with the RES re- ** + ** turned from the USIM in the volatile memory of the ME, to ** + ** avoid a synchronisation failure. The UE shall process the ** + ** authentication challenge data and respond with an AUTHEN- ** + ** TICATION RESPONSE message to the network. ** + ** ** + ** Inputs: native_ksi: TRUE if the security context is of type ** + ** native (for KSIASME) ** + ** ksi: The NAS ket sey identifier ** + ** rand: Authentication parameter RAND ** + ** autn: Authentication parameter AUTN ** + ** Others: _emm_data, _authentication_data ** + ** ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data, _authentication_data, T3416, ** + ** T3418, T3420 ** ** ** ***************************************************************************/ int emm_proc_authentication_request(int native_ksi, int ksi, - const OctetString* rand, - const OctetString* autn) + const OctetString *rand, + const OctetString *autn) { LOG_FUNC_IN; @@ -198,19 +201,19 @@ int emm_proc_authentication_request(int native_ksi, int ksi, * USIM is present */ if (!_emm_data.usim_is_valid) { - LOG_TRACE(WARNING, "EMM-PROC - USIM is not present or not valid"); - LOG_FUNC_RETURN (RETURNerror); + LOG_TRACE(WARNING, "EMM-PROC - USIM is not present or not valid"); + LOG_FUNC_RETURN (RETURNerror); } /* Stop timer T3418, if running */ if (T3418.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3418 (%d)", T3418.id); - T3418.id = nas_timer_stop(T3418.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3418 (%d)", T3418.id); + T3418.id = nas_timer_stop(T3418.id); } /* Stop timer T3420, if running */ if (T3420.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3420 (%d)", T3420.id); - T3420.id = nas_timer_stop(T3420.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3420 (%d)", T3420.id); + T3420.id = nas_timer_stop(T3420.id); } /* Setup security keys */ @@ -219,76 +222,76 @@ int emm_proc_authentication_request(int native_ksi, int ksi, OctetString res = {AUTH_RES_SIZE, _authentication_data.res}; if (memcmp(_authentication_data.rand, rand->value, AUTH_CK_SIZE) != 0) { - /* - * There is no valid stored RAND in the ME or the stored RAND is - * different from the new received value in the AUTHENTICATION - * REQUEST message - */ - OctetString auts; - auts.length = 0; - auts.value = (uint8_t*)malloc(AUTH_AUTS_SIZE); - if (auts.value == NULL) { - LOG_TRACE(WARNING, "EMM-PROC - Failed to allocate AUTS parameter"); - LOG_FUNC_RETURN (RETURNerror); - } - - /* 3GPP TS 33.401, section 6.1.1 - * Get the "separation bit" of the AMF field of AUTN */ - int sbit = AUTH_AMF_SEPARATION_BIT(autn->value[AUTH_AMF_INDEX]); - if (sbit != 0) { - /* - * Perform EPS authentication challenge to check the authenticity - * of the core network by means of the received AUTN parameter and - * request the USIM to compute RES, CK and IK for given RAND - */ - rc = usim_api_authenticate(rand, autn, &auts, &res, &ck, &ik); - } - if (rc != RETURNok) { - /* - * Network authentication not accepted by the UE - */ - LOG_TRACE(WARNING, "EMM-PROC - Network authentication failed (%s)", - (auts.length > 0) ? "SQN failure" : - (sbit == 0) ? "Non-EPS authentication unacceptable" : - "MAC code failure"); - /* Delete any previously stored RAND and RES and stop timer T3416 */ - (void) emm_proc_authentication_delete(); - /* Proceed authentication abnormal cases procedure */ - if (auts.length > 0) { - /* 3GPP TS 24.301, section 5.4.2.6, case e - * SQN failure */ - rc = _authentication_abnormal_cases_cde( - EMM_CAUSE_SYNCH_FAILURE, &auts); - } else if (sbit == 0) { - /* 3GPP TS 24.301, section 5.4.2.6, case d - * Non-EPS authentication unacceptable */ - rc = _authentication_abnormal_cases_cde( - EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE, NULL); - } else { - /* 3GPP TS 24.301, section 5.4.2.6, case c - * MAC code failure */ - rc = _authentication_abnormal_cases_cde( - EMM_CAUSE_MAC_FAILURE, NULL); - } - /* Free the AUTS parameter */ - free(auts.value); - LOG_FUNC_RETURN (rc); - } - - /* Free the AUTS parameter */ - free(auts.value); - /* Store the new RAND in the volatile memory */ - if (rand->length <= AUTH_RAND_SIZE) { - memcpy(_authentication_data.rand, rand->value, rand->length); - } - /* Start, or reset and restart timer T3416 */ - if (T3416.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", T3416.id); - T3416.id = nas_timer_stop(T3416.id); - } - T3416.id = nas_timer_start(T3416.sec, _authentication_t3416_handler, NULL); - LOG_TRACE(INFO, "EMM-PROC - Timer T3416 (%d) expires in %ld seconds", - T3416.id, T3416.sec); + /* + * There is no valid stored RAND in the ME or the stored RAND is + * different from the new received value in the AUTHENTICATION + * REQUEST message + */ + OctetString auts; + auts.length = 0; + auts.value = (uint8_t *)malloc(AUTH_AUTS_SIZE); + if (auts.value == NULL) { + LOG_TRACE(WARNING, "EMM-PROC - Failed to allocate AUTS parameter"); + LOG_FUNC_RETURN (RETURNerror); + } + + /* 3GPP TS 33.401, section 6.1.1 + * Get the "separation bit" of the AMF field of AUTN */ + int sbit = AUTH_AMF_SEPARATION_BIT(autn->value[AUTH_AMF_INDEX]); + if (sbit != 0) { + /* + * Perform EPS authentication challenge to check the authenticity + * of the core network by means of the received AUTN parameter and + * request the USIM to compute RES, CK and IK for given RAND + */ + rc = usim_api_authenticate(rand, autn, &auts, &res, &ck, &ik); + } + if (rc != RETURNok) { + /* + * Network authentication not accepted by the UE + */ + LOG_TRACE(WARNING, "EMM-PROC - Network authentication failed (%s)", + (auts.length > 0) ? "SQN failure" : + (sbit == 0) ? "Non-EPS authentication unacceptable" : + "MAC code failure"); + /* Delete any previously stored RAND and RES and stop timer T3416 */ + (void) emm_proc_authentication_delete(); + /* Proceed authentication abnormal cases procedure */ + if (auts.length > 0) { + /* 3GPP TS 24.301, section 5.4.2.6, case e + * SQN failure */ + rc = _authentication_abnormal_cases_cde( + EMM_CAUSE_SYNCH_FAILURE, &auts); + } else if (sbit == 0) { + /* 3GPP TS 24.301, section 5.4.2.6, case d + * Non-EPS authentication unacceptable */ + rc = _authentication_abnormal_cases_cde( + EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE, NULL); + } else { + /* 3GPP TS 24.301, section 5.4.2.6, case c + * MAC code failure */ + rc = _authentication_abnormal_cases_cde( + EMM_CAUSE_MAC_FAILURE, NULL); + } + /* Free the AUTS parameter */ + free(auts.value); + LOG_FUNC_RETURN (rc); + } + + /* Free the AUTS parameter */ + free(auts.value); + /* Store the new RAND in the volatile memory */ + if (rand->length <= AUTH_RAND_SIZE) { + memcpy(_authentication_data.rand, rand->value, rand->length); + } + /* Start, or reset and restart timer T3416 */ + if (T3416.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", T3416.id); + T3416.id = nas_timer_stop(T3416.id); + } + T3416.id = nas_timer_start(T3416.sec, _authentication_t3416_handler, NULL); + LOG_TRACE(INFO, "EMM-PROC - Timer T3416 (%d) expires in %ld seconds", + T3416.id, T3416.sec); } /* @@ -299,17 +302,17 @@ int emm_proc_authentication_request(int native_ksi, int ksi, /* Start any retransmission timers */ rc = _authentication_start_timers(); if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-PROC - Failed to start retransmission timers"); - LOG_FUNC_RETURN (RETURNerror); + LOG_TRACE(WARNING, "EMM-PROC - Failed to start retransmission timers"); + LOG_FUNC_RETURN (RETURNerror); } /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ rc = emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); if (rc != RETURNok) { - LOG_TRACE(WARNING, - "EMM-PROC - Failed to initialize EMM procedure handler"); - LOG_FUNC_RETURN (RETURNerror); + LOG_TRACE(WARNING, + "EMM-PROC - Failed to initialize EMM procedure handler"); + LOG_FUNC_RETURN (RETURNerror); } /* @@ -325,38 +328,38 @@ int emm_proc_authentication_request(int native_ksi, int ksi, emm_sap.u.emm_as.u.security.res = &res; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, FALSE, TRUE); + _emm_data.security, FALSE, TRUE); rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { - /* Reset the authentication failure counters */ - _authentication_data.mac_count = 0; - _authentication_data.umts_count = 0; - _authentication_data.sync_count = 0; - /* Create non-current EPS security context */ - if (_emm_data.non_current == NULL) { - _emm_data.non_current = - (emm_security_context_t*)malloc(sizeof(emm_security_context_t)); - } - if (_emm_data.non_current) { - memset(_emm_data.non_current, 0, sizeof(emm_security_context_t)); - /* Set the security context type */ - if (native_ksi) { - _emm_data.non_current->type = EMM_KSI_NATIVE; - } else { - _emm_data.non_current->type = EMM_KSI_MAPPED; - } - /* Set the EPS key set identifier */ - _emm_data.non_current->eksi = ksi; - /* Derive the Kasme from the authentication challenge using - * the PLMN identity of the selected PLMN */ - _emm_data.non_current->kasme.length = AUTH_KASME_SIZE; - _emm_data.non_current->kasme.value = - (uint8_t*)malloc(sizeof(AUTH_KASME_SIZE)); - _authentication_kasme(autn, &ck, &ik, &_emm_data.splmn, - &_emm_data.non_current->kasme); - /* NAS integrity and cyphering keys are not yet available */ - } + /* Reset the authentication failure counters */ + _authentication_data.mac_count = 0; + _authentication_data.umts_count = 0; + _authentication_data.sync_count = 0; + /* Create non-current EPS security context */ + if (_emm_data.non_current == NULL) { + _emm_data.non_current = + (emm_security_context_t *)malloc(sizeof(emm_security_context_t)); + } + if (_emm_data.non_current) { + memset(_emm_data.non_current, 0, sizeof(emm_security_context_t)); + /* Set the security context type */ + if (native_ksi) { + _emm_data.non_current->type = EMM_KSI_NATIVE; + } else { + _emm_data.non_current->type = EMM_KSI_MAPPED; + } + /* Set the EPS key set identifier */ + _emm_data.non_current->eksi = ksi; + /* Derive the Kasme from the authentication challenge using + * the PLMN identity of the selected PLMN */ + _emm_data.non_current->kasme.length = AUTH_KASME_SIZE; + _emm_data.non_current->kasme.value = + (uint8_t *)malloc(sizeof(AUTH_KASME_SIZE)); + _authentication_kasme(autn, &ck, &ik, &_emm_data.splmn, + &_emm_data.non_current->kasme); + /* NAS integrity and cyphering keys are not yet available */ + } } LOG_FUNC_RETURN (rc); @@ -364,24 +367,24 @@ int emm_proc_authentication_request(int native_ksi, int ksi, /**************************************************************************** ** ** - ** Name: emm_proc_authentication_reject() ** + ** Name: emm_proc_authentication_reject() ** ** ** ** Description: Performs the authentication procedure not accepted by the ** - ** network. ** + ** network. ** ** ** ** 3GPP TS 24.301, section 5.4.2.5 ** - ** Upon receiving an AUTHENTICATION REJECT message, the UE ** - ** shall abort any EMM signalling procedure, stop any of the ** - ** timers T3410, T3417 or T3430 (if running) and enter state ** - ** EMM-DEREGISTERED. ** + ** Upon receiving an AUTHENTICATION REJECT message, the UE ** + ** shall abort any EMM signalling procedure, stop any of the ** + ** timers T3410, T3417 or T3430 (if running) and enter state ** + ** EMM-DEREGISTERED. ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _authentication_data, T3410, ** - ** T3417, T3430 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data, _authentication_data, T3410, ** + ** T3417, T3430 ** ** ** ***************************************************************************/ int emm_proc_authentication_reject(void) @@ -406,25 +409,25 @@ int emm_proc_authentication_reject(void) _emm_data.tai = NULL; /* Delete the eKSI */ if (_emm_data.security) { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; } /* Consider the USIM invalid */ _emm_data.usim_is_valid = FALSE; /* Stop timer T3410 */ if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); + T3410.id = nas_timer_stop(T3410.id); } /* Stop timer T3417 */ if (T3417.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", T3417.id); - T3417.id = nas_timer_stop(T3417.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", T3417.id); + T3417.id = nas_timer_stop(T3417.id); } /* Stop timer T3430 */ if (T3430.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", T3430.id); - T3430.id = nas_timer_stop(T3430.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", T3430.id); + T3430.id = nas_timer_stop(T3430.id); } /* Abort any EMM signalling procedure (prevent the retransmission timers to @@ -442,24 +445,24 @@ int emm_proc_authentication_reject(void) /**************************************************************************** ** ** - ** Name: emm_proc_authentication_delete() ** + ** Name: emm_proc_authentication_delete() ** ** ** ** Description: Deletes the RAND and RES values stored into the volatile ** - ** memory of the Mobile Equipment and stop timer T3416, if ** - ** running, upon receipt of a SECURITY MODE COMMAND, SERVICE ** - ** REJECT, TRACKING AREA UPDATE REJECT, TRACKING AREA UPDATE ** - ** ACCEPT or AUTHENTICATION REJECT message; upon expiry of ** - ** timer T3416; or if the UE enters the EMM state EMM- ** - ** DEREGISTERED or EMM-NULL. ** + ** memory of the Mobile Equipment and stop timer T3416, if ** + ** running, upon receipt of a SECURITY MODE COMMAND, SERVICE ** + ** REJECT, TRACKING AREA UPDATE REJECT, TRACKING AREA UPDATE ** + ** ACCEPT or AUTHENTICATION REJECT message; upon expiry of ** + ** timer T3416; or if the UE enters the EMM state EMM- ** + ** DEREGISTERED or EMM-NULL. ** ** ** ** 3GPP TS 24.301, section 5.4.2.3 ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _authentication_data, T3416 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _authentication_data, T3416 ** ** ** ***************************************************************************/ int emm_proc_authentication_delete(void) @@ -470,8 +473,8 @@ int emm_proc_authentication_delete(void) /* Stop timer T3416, if running */ if (T3416.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", T3416.id); - T3416.id = nas_timer_stop(T3416.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", T3416.id); + T3416.id = nas_timer_stop(T3416.id); } /* Delete any previously stored RAND and RES */ memset(_authentication_data.rand, 0, AUTH_RAND_SIZE); @@ -483,47 +486,47 @@ int emm_proc_authentication_delete(void) /* * -------------------------------------------------------------------------- - * Authentication procedure executed by the MME + * Authentication procedure executed by the MME * -------------------------------------------------------------------------- */ #ifdef NAS_MME /**************************************************************************** ** ** - ** Name: emm_proc_authentication() ** + ** Name: emm_proc_authentication() ** ** ** ** Description: Initiates authentication procedure to establish partial ** - ** native EPS security context in the UE and the MME. ** + ** native EPS security context in the UE and the MME. ** ** ** ** 3GPP TS 24.301, section 5.4.2.2 ** - ** The network initiates the authentication procedure by ** - ** sending an AUTHENTICATION REQUEST message to the UE and ** - ** starting the timer T3460. The AUTHENTICATION REQUEST mes- ** - ** sage contains the parameters necessary to calculate the ** - ** authentication response. ** - ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** ksi: NAS key set identifier ** - ** rand: Random challenge number ** - ** autn: Authentication token ** - ** success: Callback function executed when the authen-** - ** tication procedure successfully completes ** - ** reject: Callback function executed when the authen-** - ** tication procedure fails or is rejected ** - ** failure: Callback function executed whener a lower ** - ** layer failure occured before the authenti- ** - ** cation procedure comnpletes ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** The network initiates the authentication procedure by ** + ** sending an AUTHENTICATION REQUEST message to the UE and ** + ** starting the timer T3460. The AUTHENTICATION REQUEST mes- ** + ** sage contains the parameters necessary to calculate the ** + ** authentication response. ** + ** ** + ** Inputs: ueid: UE lower layer identifier ** + ** ksi: NAS key set identifier ** + ** rand: Random challenge number ** + ** autn: Authentication token ** + ** success: Callback function executed when the authen-** + ** tication procedure successfully completes ** + ** reject: Callback function executed when the authen-** + ** tication procedure fails or is rejected ** + ** failure: Callback function executed whener a lower ** + ** layer failure occured before the authenti- ** + ** cation procedure comnpletes ** + ** Others: None ** + ** ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_authentication(unsigned int ueid, int ksi, - const OctetString* _rand, const OctetString* autn, - emm_common_success_callback_t success, - emm_common_reject_callback_t reject, - emm_common_failure_callback_t failure) + const OctetString *_rand, const OctetString *autn, + emm_common_success_callback_t success, + emm_common_reject_callback_t reject, + emm_common_failure_callback_t failure) { LOG_FUNC_IN; @@ -533,55 +536,55 @@ int emm_proc_authentication(unsigned int ueid, int ksi, LOG_TRACE(INFO, "EMM-PROC - Initiate authentication KSI = %d", ksi); /* Allocate parameters of the retransmission timer callback */ - authentication_data_t* data = - (authentication_data_t*)malloc(sizeof(authentication_data_t)); + authentication_data_t *data = + (authentication_data_t *)malloc(sizeof(authentication_data_t)); if (data != NULL) { - /* Setup ongoing EMM procedure callback functions */ - rc = emm_proc_common_initialize(ueid, success, reject, failure, - _authentication_abort, data); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "Failed to initialize EMM callback functions"); - LOG_FUNC_RETURN (RETURNerror); - } - - /* Set the UE identifier */ - data->ueid = ueid; - /* Reset the retransmission counter */ - data->retransmission_count = 0; - /* Set the key set identifier */ - data->ksi = ksi; - /* Set the authentication random challenge number */ + /* Setup ongoing EMM procedure callback functions */ + rc = emm_proc_common_initialize(ueid, success, reject, failure, + _authentication_abort, data); + if (rc != RETURNok) { + LOG_TRACE(WARNING, "Failed to initialize EMM callback functions"); + LOG_FUNC_RETURN (RETURNerror); + } + + /* Set the UE identifier */ + data->ueid = ueid; + /* Reset the retransmission counter */ + data->retransmission_count = 0; + /* Set the key set identifier */ + data->ksi = ksi; + /* Set the authentication random challenge number */ if (_rand->length > 0) { - data->rand.value = (uint8_t*)malloc(_rand->length); - data->rand.length = 0; - if (data->rand.value) { + data->rand.value = (uint8_t *)malloc(_rand->length); + data->rand.length = 0; + if (data->rand.value) { memcpy(data->rand.value, _rand->value, _rand->length); data->rand.length = _rand->length; - } - } - /* Set the authentication token */ - if (autn->length > 0) { - data->autn.value = (uint8_t*)malloc(autn->length); - data->autn.length = 0; - if (data->autn.value) { - memcpy(data->autn.value, autn->value, autn->length); - data->autn.length = autn->length; - } - } - /* Set the failure notification indicator */ - data->notify_failure = FALSE; - /* Send authentication request message to the UE */ - rc = _authentication_request(data); - if (rc != RETURNerror) { - /* - * Notify EMM that common procedure has been initiated - */ - emm_sap_t emm_sap; - emm_sap.primitive = EMMREG_COMMON_PROC_REQ; - emm_sap.u.emm_reg.ueid = ueid; - rc = emm_sap_send(&emm_sap); - } + } + } + /* Set the authentication token */ + if (autn->length > 0) { + data->autn.value = (uint8_t *)malloc(autn->length); + data->autn.length = 0; + if (data->autn.value) { + memcpy(data->autn.value, autn->value, autn->length); + data->autn.length = autn->length; + } + } + /* Set the failure notification indicator */ + data->notify_failure = FALSE; + /* Send authentication request message to the UE */ + rc = _authentication_request(data); + if (rc != RETURNerror) { + /* + * Notify EMM that common procedure has been initiated + */ + emm_sap_t emm_sap; + emm_sap.primitive = EMMREG_COMMON_PROC_REQ; + emm_sap.u.emm_reg.ueid = ueid; + rc = emm_sap_send(&emm_sap); + } } LOG_FUNC_RETURN (rc); @@ -589,28 +592,28 @@ int emm_proc_authentication(unsigned int ueid, int ksi, /**************************************************************************** ** ** - ** Name: emm_proc_authentication_complete() ** + ** Name: emm_proc_authentication_complete() ** ** ** ** Description: Performs the authentication completion procedure executed ** - ** by the network. ** + ** by the network. ** ** ** ** 3GPP TS 24.301, section 5.4.2.4 ** - ** Upon receiving the AUTHENTICATION RESPONSE message, the ** - ** MME shall stop timer T3460 and check the correctness of ** - ** the RES parameter. ** + ** Upon receiving the AUTHENTICATION RESPONSE message, the ** + ** MME shall stop timer T3460 and check the correctness of ** + ** the RES parameter. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** emm_cause: Authentication failure EMM cause code ** - ** res: Authentication response parameter ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** emm_cause: Authentication failure EMM cause code ** + ** res: Authentication response parameter ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, T3460 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data, T3460 ** ** ** ***************************************************************************/ int emm_proc_authentication_complete(unsigned int ueid, int emm_cause, - const OctetString* res) + const OctetString *res) { LOG_FUNC_IN; @@ -618,27 +621,27 @@ int emm_proc_authentication_complete(unsigned int ueid, int emm_cause, emm_sap_t emm_sap; LOG_TRACE(INFO, "EMM-PROC - Authentication complete (ueid=%u, cause=%d)", - ueid, emm_cause); + ueid, emm_cause); /* Stop timer T3460 */ LOG_TRACE(INFO, "EMM-PROC - Stop timer T3460 (%d)", T3460.id); T3460.id = nas_timer_stop(T3460.id); /* Release retransmission timer paramaters */ - authentication_data_t* data = - (authentication_data_t*)(emm_proc_common_get_args(ueid)); + authentication_data_t *data = + (authentication_data_t *)(emm_proc_common_get_args(ueid)); if (data) { - if (data->rand.length > 0) { - free(data->rand.value); - } - if (data->autn.length > 0) { - free(data->autn.value); - } - free(data); + if (data->rand.length > 0) { + free(data->rand.value); + } + if (data->autn.length > 0) { + free(data->autn.value); + } + free(data); } /* Get the UE context */ - emm_data_context_t* emm_ctx = NULL; + emm_data_context_t *emm_ctx = NULL; #if defined(EPC_BUILD) if (ueid > 0) { @@ -646,38 +649,37 @@ int emm_proc_authentication_complete(unsigned int ueid, int emm_cause, } #else if (ueid < EMM_DATA_NB_UE_MAX) { - emm_ctx = _emm_data.ctx[ueid]; + emm_ctx = _emm_data.ctx[ueid]; } #endif if (emm_cause == EMM_CAUSE_SUCCESS) { - /* Check the received RES parameter */ - if ( (emm_ctx == NULL) || - (memcmp(res->value, &emm_ctx->vector.xres, res->length) != 0) ) { - /* RES does not match the XRES parameter */ - LOG_TRACE(WARNING, "EMM-PROC - Failed to authentify the UE"); - emm_cause = EMM_CAUSE_ILLEGAL_UE; - } + /* Check the received RES parameter */ + if ( (emm_ctx == NULL) || + (memcmp(res->value, &emm_ctx->vector.xres, res->length) != 0) ) { + /* RES does not match the XRES parameter */ + LOG_TRACE(WARNING, "EMM-PROC - Failed to authentify the UE"); + emm_cause = EMM_CAUSE_ILLEGAL_UE; + } } if (emm_cause != EMM_CAUSE_SUCCESS) { - /* The MME received an authentication failure message or the RES - * contained in the Authentication Response message received from - * the UE does not match the XRES parameter computed by the network */ - (void) _authentication_reject(ueid); - /* - * Notify EMM that the authentication procedure failed - */ - emm_sap.primitive = EMMREG_COMMON_PROC_REJ; - emm_sap.u.emm_reg.ueid = ueid; - } - else { - /* - * Notify EMM that the authentication procedure successfully completed - */ - emm_sap.primitive = EMMREG_COMMON_PROC_CNF; - emm_sap.u.emm_reg.ueid = ueid; - emm_sap.u.emm_reg.u.common.is_attached = emm_ctx->is_attached; + /* The MME received an authentication failure message or the RES + * contained in the Authentication Response message received from + * the UE does not match the XRES parameter computed by the network */ + (void) _authentication_reject(ueid); + /* + * Notify EMM that the authentication procedure failed + */ + emm_sap.primitive = EMMREG_COMMON_PROC_REJ; + emm_sap.u.emm_reg.ueid = ueid; + } else { + /* + * Notify EMM that the authentication procedure successfully completed + */ + emm_sap.primitive = EMMREG_COMMON_PROC_CNF; + emm_sap.u.emm_reg.ueid = ueid; + emm_sap.u.emm_reg.u.common.is_attached = emm_ctx->is_attached; } rc = emm_sap_send(&emm_sap); @@ -693,29 +695,29 @@ int emm_proc_authentication_complete(unsigned int ueid, int emm_cause, #ifdef NAS_UE /* * -------------------------------------------------------------------------- - * Timer handlers + * Timer handlers * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _authentication_t3416_handler() ** + ** Name: _authentication_t3416_handler() ** ** ** ** Description: T3416 timeout handler ** - ** Upon T3416 timer expiration, the RAND and RES values sto- ** - ** red in the ME shall be deleted. ** + ** Upon T3416 timer expiration, the RAND and RES values sto- ** + ** red in the ME shall be deleted. ** ** ** ** 3GPP TS 24.301, section 5.4.2.3 ** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: T3416 ** + ** Outputs: None ** + ** Return: None ** + ** Others: T3416 ** ** ** ***************************************************************************/ -static void* _authentication_t3416_handler(void* args) +static void *_authentication_t3416_handler(void *args) { LOG_FUNC_IN; @@ -731,24 +733,24 @@ static void* _authentication_t3416_handler(void* args) /**************************************************************************** ** ** - ** Name: _authentication_t3418_handler() ** + ** Name: _authentication_t3418_handler() ** ** ** ** Description: T3418 timeout handler ** - ** Upon T3418 timer expiration, the UE shall deem that the ** - ** source of the authentication challenge is not genuine ** - ** (authentication not accepted by the UE). ** + ** Upon T3418 timer expiration, the UE shall deem that the ** + ** source of the authentication challenge is not genuine ** + ** (authentication not accepted by the UE). ** ** ** ** 3GPP TS 24.301, section 5.4.2.7, case c ** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: _authentication_data, T3418 ** + ** Outputs: None ** + ** Return: None ** + ** Others: _authentication_data, T3418 ** ** ** ***************************************************************************/ -static void* _authentication_t3418_handler(void* args) +static void *_authentication_t3418_handler(void *args) { LOG_FUNC_IN; @@ -764,7 +766,7 @@ static void* _authentication_t3418_handler(void* args) /* 3GPP TS 24.301, section 5.4.2.7, case f */ rc = _authentication_abnormal_case_f(); if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-PROC - Failed to proceed abnormal case f"); + LOG_TRACE(WARNING, "EMM-PROC - Failed to proceed abnormal case f"); } LOG_FUNC_RETURN (NULL); @@ -772,23 +774,23 @@ static void* _authentication_t3418_handler(void* args) /**************************************************************************** ** ** - ** Name: _authentication_t3420_handler() ** + ** Name: _authentication_t3420_handler() ** ** ** ** Description: T3420 timeout handler ** - ** Upon T3420 timer expiration, the UE shall deem that the ** - ** network has failed the authentication check. ** + ** Upon T3420 timer expiration, the UE shall deem that the ** + ** network has failed the authentication check. ** ** ** ** 3GPP TS 24.301, section 5.4.2.7, case e ** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: _authentication_data, T3420 ** + ** Outputs: None ** + ** Return: None ** + ** Others: _authentication_data, T3420 ** ** ** ***************************************************************************/ -static void* _authentication_t3420_handler(void* args) +static void *_authentication_t3420_handler(void *args) { LOG_FUNC_IN; @@ -803,7 +805,7 @@ static void* _authentication_t3420_handler(void* args) /* 3GPP TS 24.301, section 5.4.2.7, case f */ rc = _authentication_abnormal_case_f(); if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-PROC - Failed to proceed abnormal case f"); + LOG_TRACE(WARNING, "EMM-PROC - Failed to proceed abnormal case f"); } LOG_FUNC_RETURN (NULL); @@ -811,37 +813,37 @@ static void* _authentication_t3420_handler(void* args) /* * -------------------------------------------------------------------------- - * Abnormal cases in the UE + * Abnormal cases in the UE * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _authentication_abnormal_cases_cde() ** + ** Name: _authentication_abnormal_cases_cde() ** ** ** ** Description: Performs the abnormal case authentication procedure. ** ** ** - ** 3GPP TS 24.301, section 5.4.2.7, cases c, d and e ** + ** 3GPP TS 24.301, section 5.4.2.7, cases c, d and e ** ** ** - ** Inputs: emm_cause: EMM cause code ** - ** Others: None ** + ** Inputs: emm_cause: EMM cause code ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _authentication_data, T3418, T3420 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _authentication_data, T3418, T3420 ** ** ** ***************************************************************************/ static int _authentication_abnormal_cases_cde(int emm_cause, - const OctetString* auts) + const OctetString *auts) { LOG_FUNC_IN; int rc; LOG_TRACE(WARNING, "EMM-PROC - " - "Abnormal case, authentication counters c/d/e = %d/%d/%d", - _authentication_data.mac_count, _authentication_data.umts_count, - _authentication_data.sync_count); + "Abnormal case, authentication counters c/d/e = %d/%d/%d", + _authentication_data.mac_count, _authentication_data.umts_count, + _authentication_data.sync_count); /* * Notify EMM-AS SAP that Authentication Failure message has to be sent @@ -856,82 +858,81 @@ static int _authentication_abnormal_cases_cde(int emm_cause, emm_sap.u.emm_as.u.security.auts = auts; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, FALSE, TRUE); + _emm_data.security, FALSE, TRUE); rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { - /* - * Update the authentication failure counters - */ - switch (emm_cause) - { - case EMM_CAUSE_MAC_FAILURE: - /* 3GPP TS 24.301, section 5.4.2.6, case c - * Update the MAC failure counter */ - _authentication_data.mac_count += 1; - /* Start timer T3418 */ - T3418.id = nas_timer_start(T3418.sec, - _authentication_t3418_handler, NULL); - LOG_TRACE(INFO,"EMM-PROC - Timer T3418 (%d) expires in " - "%ld seconds", T3418.id, T3418.sec); - break; - - case EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE: - /* 3GPP TS 24.301, section 5.4.2.6, case d - * Update the UMTS challenge failure counter */ - _authentication_data.umts_count += 1; - /* Start timer T3418 */ - T3418.id = nas_timer_start(T3418.sec, - _authentication_t3418_handler, NULL); - LOG_TRACE(INFO,"EMM-PROC - Timer T3418 (%d) expires in " - "%ld seconds", T3418.id, T3418.sec); - break; - - case EMM_CAUSE_SYNCH_FAILURE: - /* 3GPP TS 24.301, section 5.4.2.6, case e - * Update the synch failure counter */ - _authentication_data.sync_count += 1; - /* Start timer T3420 */ - T3420.id = nas_timer_start(T3420.sec, - _authentication_t3420_handler, NULL); - LOG_TRACE(INFO,"EMM-PROC - Timer T3420 (%d) expires in " - "%ld seconds", T3420.id, T3420.sec); - break; - - default: - LOG_TRACE(WARNING, "EMM cause code is not valid (%d)", - emm_cause); - LOG_FUNC_RETURN (RETURNerror); - } - /* - * Stop any retransmission timers that are running - */ - rc = _authentication_stop_timers(); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-PROC - " - "Failed to stop retransmission timers"); - LOG_FUNC_RETURN (RETURNerror); - } - /* - * Check whether the network has failed the authentication check - */ - int failure_counter = 0; - if (emm_cause == EMM_CAUSE_MAC_FAILURE) { - failure_counter = _authentication_data.mac_count - + _authentication_data.sync_count; - } else if (emm_cause == EMM_CAUSE_SYNCH_FAILURE) { - failure_counter = _authentication_data.mac_count - + _authentication_data.umts_count - + _authentication_data.sync_count; - } - if (failure_counter >= AUTHENTICATION_COUNTER_MAX) { - /* 3GPP TS 24.301, section 5.4.2.6, case f */ - rc = _authentication_abnormal_case_f(); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-PROC - " - "Failed to proceed abnormal case f"); - } - } + /* + * Update the authentication failure counters + */ + switch (emm_cause) { + case EMM_CAUSE_MAC_FAILURE: + /* 3GPP TS 24.301, section 5.4.2.6, case c + * Update the MAC failure counter */ + _authentication_data.mac_count += 1; + /* Start timer T3418 */ + T3418.id = nas_timer_start(T3418.sec, + _authentication_t3418_handler, NULL); + LOG_TRACE(INFO,"EMM-PROC - Timer T3418 (%d) expires in " + "%ld seconds", T3418.id, T3418.sec); + break; + + case EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE: + /* 3GPP TS 24.301, section 5.4.2.6, case d + * Update the UMTS challenge failure counter */ + _authentication_data.umts_count += 1; + /* Start timer T3418 */ + T3418.id = nas_timer_start(T3418.sec, + _authentication_t3418_handler, NULL); + LOG_TRACE(INFO,"EMM-PROC - Timer T3418 (%d) expires in " + "%ld seconds", T3418.id, T3418.sec); + break; + + case EMM_CAUSE_SYNCH_FAILURE: + /* 3GPP TS 24.301, section 5.4.2.6, case e + * Update the synch failure counter */ + _authentication_data.sync_count += 1; + /* Start timer T3420 */ + T3420.id = nas_timer_start(T3420.sec, + _authentication_t3420_handler, NULL); + LOG_TRACE(INFO,"EMM-PROC - Timer T3420 (%d) expires in " + "%ld seconds", T3420.id, T3420.sec); + break; + + default: + LOG_TRACE(WARNING, "EMM cause code is not valid (%d)", + emm_cause); + LOG_FUNC_RETURN (RETURNerror); + } + /* + * Stop any retransmission timers that are running + */ + rc = _authentication_stop_timers(); + if (rc != RETURNok) { + LOG_TRACE(WARNING, "EMM-PROC - " + "Failed to stop retransmission timers"); + LOG_FUNC_RETURN (RETURNerror); + } + /* + * Check whether the network has failed the authentication check + */ + int failure_counter = 0; + if (emm_cause == EMM_CAUSE_MAC_FAILURE) { + failure_counter = _authentication_data.mac_count + + _authentication_data.sync_count; + } else if (emm_cause == EMM_CAUSE_SYNCH_FAILURE) { + failure_counter = _authentication_data.mac_count + + _authentication_data.umts_count + + _authentication_data.sync_count; + } + if (failure_counter >= AUTHENTICATION_COUNTER_MAX) { + /* 3GPP TS 24.301, section 5.4.2.6, case f */ + rc = _authentication_abnormal_case_f(); + if (rc != RETURNok) { + LOG_TRACE(WARNING, "EMM-PROC - " + "Failed to proceed abnormal case f"); + } + } } LOG_FUNC_RETURN (rc); @@ -939,18 +940,18 @@ static int _authentication_abnormal_cases_cde(int emm_cause, /**************************************************************************** ** ** - ** Name: _authentication_abnormal_case_f() ** + ** Name: _authentication_abnormal_case_f() ** ** ** ** Description: Performs the abnormal case authentication procedure. ** ** ** - ** 3GPP TS 24.301, section 5.4.2.7, case f ** + ** 3GPP TS 24.301, section 5.4.2.7, case f ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ static int _authentication_abnormal_case_f(void) @@ -972,11 +973,11 @@ static int _authentication_abnormal_case_f(void) rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { - /* Start any retransmission timers (e.g. T3410, T3417, T3421 or - * T3430), if they were running and stopped when the UE received - * the first AUTHENTICATION REQUEST message containing an invalid - * MAC or SQN */ - rc = _authentication_start_timers(); + /* Start any retransmission timers (e.g. T3410, T3417, T3421 or + * T3430), if they were running and stopped when the UE received + * the first AUTHENTICATION REQUEST message containing an invalid + * MAC or SQN */ + rc = _authentication_start_timers(); } LOG_FUNC_RETURN (rc); @@ -984,24 +985,24 @@ static int _authentication_abnormal_case_f(void) /* * -------------------------------------------------------------------------- - * UE specific local functions + * UE specific local functions * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _authentication_stop_timers() ** + ** Name: _authentication_stop_timers() ** ** ** ** Description: Stops any retransmission timers (e.g. T3410, T3417, T3421 ** - ** or T3430) that are running ** + ** or T3430) that are running ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _authentication_data, T3410, T3417, T3421, ** - ** T3430 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _authentication_data, T3410, T3417, T3421, ** + ** T3430 ** ** ** ***************************************************************************/ static int _authentication_stop_timers(void) @@ -1010,27 +1011,27 @@ static int _authentication_stop_timers(void) /* Stop attach timer */ if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); - _authentication_data.timers |= AUTHENTICATION_T3410; + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); + T3410.id = nas_timer_stop(T3410.id); + _authentication_data.timers |= AUTHENTICATION_T3410; } /* Stop service request timer */ if (T3417.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", T3417.id); - T3417.id = nas_timer_stop(T3417.id); - _authentication_data.timers |= AUTHENTICATION_T3417; + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", T3417.id); + T3417.id = nas_timer_stop(T3417.id); + _authentication_data.timers |= AUTHENTICATION_T3417; } /* Stop detach timer */ if (T3421.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3421 (%d)", T3421.id); - T3421.id = nas_timer_stop(T3421.id); - _authentication_data.timers |= AUTHENTICATION_T3421; + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3421 (%d)", T3421.id); + T3421.id = nas_timer_stop(T3421.id); + _authentication_data.timers |= AUTHENTICATION_T3421; } /* Stop tracking area update timer */ if (T3430.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", T3430.id); - T3430.id = nas_timer_stop(T3430.id); - _authentication_data.timers |= AUTHENTICATION_T3430; + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", T3430.id); + T3430.id = nas_timer_stop(T3430.id); + _authentication_data.timers |= AUTHENTICATION_T3430; } LOG_FUNC_RETURN (RETURNok); @@ -1038,21 +1039,21 @@ static int _authentication_stop_timers(void) /**************************************************************************** ** ** - ** Name: _authentication_start_timers() ** + ** Name: _authentication_start_timers() ** ** ** ** Description: Starts any retransmission timers (e.g. T3410, T3417, ** - ** T3421 or T3430), if they were running and stopped when ** - ** the UE received the first AUTHENTICATION REQUEST message ** - ** containing an invalid MAC or SQN ** + ** T3421 or T3430), if they were running and stopped when ** + ** the UE received the first AUTHENTICATION REQUEST message ** + ** containing an invalid MAC or SQN ** ** ** - ** 3GPP TS 24.301, section 5.4.2.7, case f ** + ** 3GPP TS 24.301, section 5.4.2.7, case f ** ** ** - ** Inputs: None ** - ** Others: _authentication_data ** + ** Inputs: None ** + ** Others: _authentication_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3410, T3417, T3421, T3430 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3410, T3417, T3421, T3430 ** ** ** ***************************************************************************/ static int _authentication_start_timers(void) @@ -1060,28 +1061,28 @@ static int _authentication_start_timers(void) LOG_FUNC_IN; if (_authentication_data.timers & AUTHENTICATION_T3410) { - /* Start attach timer */ - T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, NULL); - LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in " - "%ld seconds", T3410.id, T3410.sec); + /* Start attach timer */ + T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, NULL); + LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in " + "%ld seconds", T3410.id, T3410.sec); } if (_authentication_data.timers & AUTHENTICATION_T3417) { - /* Start service request timer */ - T3417.id = nas_timer_start(T3417.sec, _emm_service_t3417_handler, NULL); - LOG_TRACE(INFO,"EMM-PROC - Timer T3417 (%d) expires in " - "%ld seconds", T3417.id, T3417.sec); + /* Start service request timer */ + T3417.id = nas_timer_start(T3417.sec, _emm_service_t3417_handler, NULL); + LOG_TRACE(INFO,"EMM-PROC - Timer T3417 (%d) expires in " + "%ld seconds", T3417.id, T3417.sec); } if (_authentication_data.timers & AUTHENTICATION_T3421) { - /* Start detach 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); + /* Start detach 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); } if (_authentication_data.timers & AUTHENTICATION_T3430) { - /* Start tracking area update timer */ - T3430.id = nas_timer_start(T3430.sec, _emm_tau_t3430_handler, NULL); - LOG_TRACE(INFO,"EMM-PROC - Timer T3430 (%d) expires in " - "%ld seconds", T3430.id, T3430.sec); + /* Start tracking area update timer */ + T3430.id = nas_timer_start(T3430.sec, _emm_tau_t3430_handler, NULL); + LOG_TRACE(INFO,"EMM-PROC - Timer T3430 (%d) expires in " + "%ld seconds", T3430.id, T3430.sec); } LOG_FUNC_RETURN (RETURNok); @@ -1089,27 +1090,27 @@ static int _authentication_start_timers(void) /**************************************************************************** ** ** - ** Name: _authentication_kasme() ** + ** Name: _authentication_kasme() ** ** ** ** Description: Computes the Key Access Security Management Entity Kasme ** - ** from the provided authentication challenge data. ** + ** from the provided authentication challenge data. ** ** ** ** 3GPP TS 33.401, Annex A.2 ** ** ** - ** Inputs: autn: Authentication token ** - ** ck: Cipherig key ** - ** ik: Integrity key ** - ** plmn: Identifier of the currently selected PLMN ** - ** Others: None ** + ** Inputs: autn: Authentication token ** + ** ck: Cipherig key ** + ** ik: Integrity key ** + ** plmn: Identifier of the currently selected PLMN ** + ** Others: None ** ** ** - ** Outputs: kasme: Key Access Security Management Entity ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: kasme: Key Access Security Management Entity ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -static int _authentication_kasme(const OctetString* autn, - const OctetString* ck, const OctetString* ik, - const plmn_t* plmn, OctetString* kasme) +static int _authentication_kasme(const OctetString *autn, + const OctetString *ck, const OctetString *ik, + const plmn_t *plmn, OctetString *kasme) { LOG_FUNC_IN; @@ -1125,12 +1126,16 @@ static int _authentication_kasme(const OctetString* autn, UInt16_t length; int offset = 0; int size_of_length = sizeof(length); - input[offset] = 0x10; offset += 1; + input[offset] = 0x10; + offset += 1; length = AUTH_SNID_SIZE; - memcpy(input + offset, plmn, length); offset += length; - memcpy(input + offset, &length, size_of_length); offset += size_of_length; + memcpy(input + offset, plmn, length); + offset += length; + memcpy(input + offset, &length, size_of_length); + offset += size_of_length; length = AUTH_SQN_SIZE; - memcpy(input + offset, autn, length); offset += length; + memcpy(input + offset, autn, length); + offset += length; memcpy(input + offset, &length, size_of_length); /* TODO !!! Compute the Kasme key */ @@ -1143,64 +1148,63 @@ static int _authentication_kasme(const OctetString* autn, #ifdef NAS_MME /* * -------------------------------------------------------------------------- - * Timer handlers + * Timer handlers * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _authentication_t3460_handler() ** + ** 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. ** + ** 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 ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ -static void* _authentication_t3460_handler(void* args) +static void *_authentication_t3460_handler(void *args) { LOG_FUNC_IN; int rc; - authentication_data_t* data = (authentication_data_t*)(args); + 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); + "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); - } + /* 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); @@ -1208,25 +1212,25 @@ static void* _authentication_t3460_handler(void* args) /* * -------------------------------------------------------------------------- - * MME specific local functions + * MME specific local functions * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _authentication_request() ** + ** Name: _authentication_request() ** ** ** ** Description: Sends AUTHENTICATION REQUEST message and start timer T3460** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3460 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3460 ** ** ** ***************************************************************************/ -int _authentication_request(authentication_data_t* data) +int _authentication_request(authentication_data_t *data) { LOG_FUNC_IN; @@ -1259,16 +1263,16 @@ int _authentication_request(authentication_data_t* data) rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { - if (T3460.id != NAS_TIMER_INACTIVE_ID) { - /* Re-start T3460 timer */ - T3460.id = nas_timer_restart(T3460.id); - } else { - /* Start T3460 timer */ - T3460.id = nas_timer_start(T3460.sec, _authentication_t3460_handler, - data); - } - LOG_TRACE(INFO,"EMM-PROC - Timer T3460 (%d) expires in %ld seconds", - T3460.id, T3460.sec); + if (T3460.id != NAS_TIMER_INACTIVE_ID) { + /* Re-start T3460 timer */ + T3460.id = nas_timer_restart(T3460.id); + } else { + /* Start T3460 timer */ + T3460.id = nas_timer_start(T3460.sec, _authentication_t3460_handler, + data); + } + LOG_TRACE(INFO,"EMM-PROC - Timer T3460 (%d) expires in %ld seconds", + T3460.id, T3460.sec); } LOG_FUNC_RETURN (rc); @@ -1276,16 +1280,16 @@ int _authentication_request(authentication_data_t* data) /**************************************************************************** ** ** - ** Name: _authentication_reject() ** + ** Name: _authentication_reject() ** ** ** ** Description: Sends AUTHENTICATION REJECT message ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ static int _authentication_reject(unsigned int ueid) @@ -1320,59 +1324,58 @@ static int _authentication_reject(unsigned int ueid) /**************************************************************************** ** ** - ** Name: _authentication_abort() ** + ** Name: _authentication_abort() ** ** ** ** Description: Aborts the authentication procedure currently in progress ** ** ** - ** Inputs: args: Authentication data to be released ** - ** Others: None ** + ** Inputs: args: Authentication data to be released ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3460 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3460 ** ** ** ***************************************************************************/ -static int _authentication_abort(void* args) +static int _authentication_abort(void *args) { LOG_FUNC_IN; int rc = RETURNerror; - 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=%u)", ueid); - - /* Stop timer T3460 */ - if (T3460.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3460 (%d)", T3460.id); - T3460.id = nas_timer_stop(T3460.id); - } - /* 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; - } + 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=%u)", ueid); + + /* Stop timer T3460 */ + if (T3460.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3460 (%d)", T3460.id); + T3460.id = nas_timer_stop(T3460.id); + } + /* 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); diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/Detach.c b/openair-cn/NAS/EURECOM-NAS/src/emm/Detach.c index 795107cedffc15a6695bdcebe963c874f6dcf3e0..e3f18083888809f0af85c9946e1c5a7648329820 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/Detach.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/Detach.c @@ -1,28 +1,28 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source Detach.c +Source Detach.c -Version 0.1 +Version 0.1 -Date 2013/05/07 +Date 2013/05/07 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines the detach related EMM procedure executed by the - Non-Access Stratum. +Description Defines the detach related EMM procedure executed by the + Non-Access Stratum. - The detach procedure is used by the UE to detach for EPS servi- - ces, to disconnect from the last PDN it is connected to; by the - network to inform the UE that it is detached for EPS services - or non-EPS services or both, to disconnect the UE from the last - PDN to which it is connected and to inform the UE to re-attach - to the network and re-establish all PDN connections. + The detach procedure is used by the UE to detach for EPS servi- + ces, to disconnect from the last PDN it is connected to; by the + network to inform the UE that it is detached for EPS services + or non-EPS services or both, to disconnect the UE from the last + PDN to which it is connected and to inform the UE to re-attach + to the network and re-establish all PDN connections. *****************************************************************************/ @@ -35,7 +35,7 @@ Description Defines the detach related EMM procedure executed by the #include "emm_sap.h" #include "esm_sap.h" -#include <stdlib.h> // free +#include <stdlib.h> // free /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -46,21 +46,21 @@ Description Defines the detach related EMM procedure executed by the /****************************************************************************/ /* String representation of the detach type */ -static const char* _emm_detach_type_str[] = { +static const char *_emm_detach_type_str[] = { "EPS", "IMSI", "EPS/IMSI", "RE-ATTACH REQUIRED", "RE-ATTACH NOT REQUIRED", "RESERVED" }; /* * -------------------------------------------------------------------------- - * Internal data handled by the detach procedure in the UE + * Internal data handled by the detach procedure in the UE * -------------------------------------------------------------------------- */ #ifdef NAS_UE /* * Timer handlers */ -void* _emm_detach_t3421_handler(void*); +void *_emm_detach_t3421_handler(void *); /* * Abnormal case detach procedures @@ -71,18 +71,18 @@ static int _emm_detach_abort(emm_proc_detach_type_t type); * Internal data used for detach procedure */ static struct { -#define EMM_DETACH_COUNTER_MAX 5 - unsigned int count; /* Counter used to limit the number of - * subsequently detach attempts */ - int switch_off; /* UE switch-off indicator */ +#define EMM_DETACH_COUNTER_MAX 5 + unsigned int count; /* Counter used to limit the number of + * subsequently detach attempts */ + int switch_off; /* UE switch-off indicator */ emm_proc_detach_type_t type; /* Type of the detach procedure - * currently in progress */ + * currently in progress */ } _emm_detach_data = {0, FALSE, EMM_DETACH_TYPE_RESERVED}; #endif // NAS_UE /* * -------------------------------------------------------------------------- - * Internal data handled by the detach procedure in the MME + * Internal data handled by the detach procedure in the MME * -------------------------------------------------------------------------- */ #ifdef NAS_MME @@ -94,31 +94,31 @@ static struct { /* * -------------------------------------------------------------------------- - * Detach procedure executed by the UE + * Detach procedure executed by the UE * -------------------------------------------------------------------------- */ #ifdef NAS_UE /**************************************************************************** ** ** - ** Name: emm_proc_detach() ** + ** Name: emm_proc_detach() ** ** ** ** Description: Initiates the detach procedure in order for the UE to de- ** - ** tach for EPS services. ** + ** 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. ** + ** 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 ** + ** 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 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_detach_data ** ** ** ***************************************************************************/ int emm_proc_detach(emm_proc_detach_type_t type, int switch_off) @@ -130,7 +130,7 @@ int emm_proc_detach(emm_proc_detach_type_t type, int switch_off) int rc; LOG_TRACE(INFO, "EMM-PROC - Initiate EPS detach type = %s (%d)", - _emm_detach_type_str[type], type); + _emm_detach_type_str[type], type); /* Initialize the detach procedure internal data */ _emm_detach_data.count = 0; @@ -140,11 +140,11 @@ int emm_proc_detach(emm_proc_detach_type_t type, int switch_off) /* 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); + 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); + LOG_TRACE(WARNING, "Failed to initialize EMM procedure handler"); + LOG_FUNC_RETURN (RETURNerror); } /* Setup NAS information message to transfer */ @@ -173,21 +173,21 @@ int emm_proc_detach(emm_proc_detach_type_t type, int switch_off) /**************************************************************************** ** ** - ** Name: emm_proc_detach_request() ** + ** 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. ** + ** from lower layers that Detach Request message has been ** + ** successfully delivered to the network. ** ** ** - ** Inputs: args: Not used ** - ** Others: None ** + ** Inputs: args: Not used ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3421 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3421 ** ** ** ***************************************************************************/ -int emm_proc_detach_request(void* args) +int emm_proc_detach_request(void *args) { LOG_FUNC_IN; @@ -195,10 +195,10 @@ int emm_proc_detach_request(void* args) 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); + /* 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); } /* @@ -212,24 +212,24 @@ int emm_proc_detach_request(void* args) /**************************************************************************** ** ** - ** Name: emm_proc_detach_accept() ** + ** Name: emm_proc_detach_accept() ** ** ** ** Description: Performs the UE initiated detach procedure for EPS servi- ** - ** ces only When the DETACH ACCEPT message is received from ** - ** the network. ** + ** ces only When the DETACH ACCEPT message is received from ** + ** the network. ** ** ** ** 3GPP TS 24.301, section 5.5.2.2.2 ** ** Upon receiving the DETACH ACCEPT message, the UE shall ** - ** stop timer T3421, locally deactivate all EPS bearer con- ** - ** texts without peer-to-peer signalling and enter state EMM-** - ** DEREGISTERED. ** + ** stop timer T3421, locally deactivate all EPS bearer con- ** + ** texts without peer-to-peer signalling and enter state EMM-** + ** DEREGISTERED. ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3421 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3421 ** ** ** ***************************************************************************/ int emm_proc_detach_accept(void) @@ -264,24 +264,24 @@ int emm_proc_detach_accept(void) /**************************************************************************** ** ** - ** Name: emm_proc_detach_failure() ** + ** Name: emm_proc_detach_failure() ** ** ** ** Description: Performs the detach procedure abnormal case upon receipt ** - ** of transmission failure of Detach Request message. ** + ** 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. ** + ** The UE shall restart the detach procedure. ** ** ** - ** Inputs: is_initial: Not used ** - ** args: Not used ** - ** Others: _emm_detach_data ** + ** Inputs: is_initial: Not used ** + ** args: Not used ** + ** Others: _emm_detach_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_detach_failure(int is_initial, void* args) +int emm_proc_detach_failure(int is_initial, void *args) { LOG_FUNC_IN; @@ -308,24 +308,24 @@ int emm_proc_detach_failure(int is_initial, void* args) /**************************************************************************** ** ** - ** Name: emm_proc_detach_release() ** + ** Name: emm_proc_detach_release() ** ** ** ** Description: Performs the detach procedure abnormal case upon receipt ** - ** of NAS signalling connection release indication before ** - ** reception of Detach Accept message. ** + ** of NAS signalling connection release indication before ** + ** reception of Detach Accept message. ** ** ** ** 3GPP TS 24.301, section 5.5.2.2.4, case b ** - ** The detach procedure shall be aborted. ** + ** The detach procedure shall be aborted. ** ** ** - ** Inputs: args: not used ** - ** Others: _emm_detach_data ** + ** Inputs: args: not used ** + ** Others: _emm_detach_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_detach_release(void* args) +int emm_proc_detach_release(void *args) { LOG_FUNC_IN; @@ -340,31 +340,31 @@ int emm_proc_detach_release(void* args) /* * -------------------------------------------------------------------------- - * Detach procedure executed by the MME + * Detach procedure executed by the MME * -------------------------------------------------------------------------- */ #ifdef NAS_MME /**************************************************************************** ** ** - ** Name: emm_proc_detach() ** + ** Name: emm_proc_detach() ** ** ** ** Description: Initiate the detach procedure to inform the UE that it is ** - ** detached for EPS services, or to re-attach to the network ** - ** and re-establish all PDN connections. ** + ** detached for EPS services, or to re-attach to the network ** + ** and re-establish all PDN connections. ** ** ** ** 3GPP TS 24.301, section 5.5.2.3.1 ** - ** In state EMM-REGISTERED the network initiates the detach ** - ** procedure by sending a DETACH REQUEST message to the UE, ** - ** starting timer T3422 and entering state EMM-DEREGISTERED- ** - ** INITIATED. ** + ** In state EMM-REGISTERED the network initiates the detach ** + ** procedure by sending a DETACH REQUEST message to the UE, ** + ** starting timer T3422 and entering state EMM-DEREGISTERED- ** + ** INITIATED. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** type: Type of the requested detach ** - ** Others: _emm_detach_type_str ** + ** Inputs: ueid: UE lower layer identifier ** + ** type: Type of the requested detach ** + ** Others: _emm_detach_type_str ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3422 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3422 ** ** ** ***************************************************************************/ int emm_proc_detach(unsigned int ueid, emm_proc_detach_type_t type) @@ -374,7 +374,7 @@ int emm_proc_detach(unsigned int ueid, emm_proc_detach_type_t type) int rc = RETURNerror; LOG_TRACE(INFO, "EMM-PROC - Initiate detach type = %s (%d)", - _emm_detach_type_str[type], type); + _emm_detach_type_str[type], type); /* TODO */ @@ -383,51 +383,51 @@ int emm_proc_detach(unsigned int ueid, emm_proc_detach_type_t type) /**************************************************************************** ** ** - ** Name: emm_proc_detach_request() ** + ** Name: emm_proc_detach_request() ** ** ** ** Description: Performs the UE initiated detach procedure for EPS servi- ** - ** ces only When the DETACH REQUEST message is received by ** - ** the network. ** + ** ces only When the DETACH REQUEST message is received by ** + ** the network. ** ** ** ** 3GPP TS 24.301, section 5.5.2.2.2 ** - ** Upon receiving the DETACH REQUEST message the network ** - ** shall send a DETACH ACCEPT message to the UE and store ** - ** the current EPS security context, if the detach type IE ** - ** does not indicate "switch off". Otherwise, the procedure ** - ** is completed when the network receives the DETACH REQUEST ** - ** message. ** - ** The network shall deactivate the EPS bearer context(s) ** - ** for this UE locally without peer-to-peer signalling and ** - ** shall enter state EMM-DEREGISTERED. ** - ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** type: Type of the requested detach ** - ** switch_off: Indicates whether the detach is required ** - ** because the UE is switched off or not ** - ** native_ksi: TRUE if the security context is of type ** - ** native ** - ** ksi: The NAS ket sey identifier ** - ** guti: The GUTI if provided by the UE ** - ** imsi: The IMSI if provided by the UE ** - ** imei: The IMEI if provided by the UE ** - ** Others: _emm_data ** - ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Upon receiving the DETACH REQUEST message the network ** + ** shall send a DETACH ACCEPT message to the UE and store ** + ** the current EPS security context, if the detach type IE ** + ** does not indicate "switch off". Otherwise, the procedure ** + ** is completed when the network receives the DETACH REQUEST ** + ** message. ** + ** The network shall deactivate the EPS bearer context(s) ** + ** for this UE locally without peer-to-peer signalling and ** + ** shall enter state EMM-DEREGISTERED. ** + ** ** + ** Inputs: ueid: UE lower layer identifier ** + ** type: Type of the requested detach ** + ** switch_off: Indicates whether the detach is required ** + ** because the UE is switched off or not ** + ** native_ksi: TRUE if the security context is of type ** + ** native ** + ** ksi: The NAS ket sey identifier ** + ** guti: The GUTI if provided by the UE ** + ** imsi: The IMSI if provided by the UE ** + ** imei: The IMEI if provided by the UE ** + ** Others: _emm_data ** + ** ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_detach_request(unsigned int ueid, emm_proc_detach_type_t type, - int switch_off, int native_ksi, int ksi, - GUTI_t* guti, imsi_t* imsi, imei_t* imei) + int switch_off, int native_ksi, int ksi, + GUTI_t *guti, imsi_t *imsi, imei_t *imei) { LOG_FUNC_IN; int rc; - emm_data_context_t* emm_ctx = NULL; + emm_data_context_t *emm_ctx = NULL; LOG_TRACE(INFO, "EMM-PROC - Detach type = %s (%d) requested (ueid=%u)", - _emm_detach_type_str[type], type, ueid); + _emm_detach_type_str[type], type, ueid); /* Get the UE context */ #if defined(EPC_BUILD) @@ -436,82 +436,94 @@ int emm_proc_detach_request(unsigned int ueid, emm_proc_detach_type_t type, } #else if (ueid < EMM_DATA_NB_UE_MAX) { - emm_ctx = _emm_data.ctx[ueid]; + emm_ctx = _emm_data.ctx[ueid]; } #endif if (emm_ctx == NULL) { - LOG_TRACE(WARNING, "No EMM context exists for the UE (ueid=%u)", ueid); - LOG_FUNC_RETURN(RETURNok); + LOG_TRACE(WARNING, "No EMM context exists for the UE (ueid=%u)", ueid); + LOG_FUNC_RETURN(RETURNok); } - if (switch_off) - { - /* The UE is switched off */ - if (emm_ctx->guti) free(emm_ctx->guti); - if (emm_ctx->imsi) free(emm_ctx->imsi); - if (emm_ctx->imei) free(emm_ctx->imei); - if (emm_ctx->esm_msg.length > 0) free(emm_ctx->esm_msg.value); - /* Release NAS security context */ - if (emm_ctx->security) { - emm_security_context_t* security = emm_ctx->security; - if (security->kasme.value) free(security->kasme.value); - if (security->knas_enc.value) free(security->knas_enc.value); - if (security->knas_int.value) free(security->knas_int.value); - free(emm_ctx->security); - } - /* Release the EMM context */ + if (switch_off) { + /* The UE is switched off */ + if (emm_ctx->guti) { + free(emm_ctx->guti); + } + if (emm_ctx->imsi) { + free(emm_ctx->imsi); + } + if (emm_ctx->imei) { + free(emm_ctx->imei); + } + if (emm_ctx->esm_msg.length > 0) { + free(emm_ctx->esm_msg.value); + } + /* Release NAS security context */ + if (emm_ctx->security) { + emm_security_context_t *security = emm_ctx->security; + if (security->kasme.value) { + free(security->kasme.value); + } + if (security->knas_enc.value) { + free(security->knas_enc.value); + } + if (security->knas_int.value) { + free(security->knas_int.value); + } + free(emm_ctx->security); + } + /* Release the EMM context */ #if defined(EPC_BUILD) emm_data_context_remove(&_emm_data, emm_ctx); free(emm_ctx); #else - free(_emm_data.ctx[ueid]); - _emm_data.ctx[ueid] = NULL; + free(_emm_data.ctx[ueid]); + _emm_data.ctx[ueid] = NULL; #endif - rc = RETURNok; - } - else { - /* Normal detach without UE switch-off */ - emm_sap_t emm_sap; - emm_as_data_t *emm_as = &emm_sap.u.emm_as.u.data; - - /* 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 UE identifier */ - emm_as->guti = NULL; - emm_as->ueid = ueid; - /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, emm_ctx->security, FALSE, TRUE); - /* - * Notify EMM-AS SAP that Detach Accept message has to - * be sent to the network - */ - emm_sap.primitive = EMMAS_DATA_REQ; - rc = emm_sap_send(&emm_sap); + rc = RETURNok; + } else { + /* Normal detach without UE switch-off */ + emm_sap_t emm_sap; + emm_as_data_t *emm_as = &emm_sap.u.emm_as.u.data; + + /* 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 UE identifier */ + emm_as->guti = NULL; + emm_as->ueid = ueid; + /* Setup EPS NAS security data */ + emm_as_set_security_data(&emm_as->sctx, emm_ctx->security, FALSE, TRUE); + /* + * Notify EMM-AS SAP that Detach Accept message has to + * be sent to the network + */ + emm_sap.primitive = EMMAS_DATA_REQ; + rc = emm_sap_send(&emm_sap); } if (rc != RETURNerror) { - /* - * Notify ESM that all EPS bearer contexts allocated for this UE have - * to be locally deactivated - */ - esm_sap_t esm_sap; - esm_sap.primitive = ESM_EPS_BEARER_CONTEXT_DEACTIVATE_REQ; - esm_sap.ueid = ueid; - esm_sap.data.eps_bearer_context_deactivate.ebi = ESM_SAP_ALL_EBI; - rc = esm_sap_send(&esm_sap); - - if (rc != RETURNerror) { - emm_sap_t emm_sap; - /* - * Notify EMM that the UE has been implicitly detached - */ - emm_sap.primitive = EMMREG_DETACH_REQ; - emm_sap.u.emm_reg.ueid = ueid; - rc = emm_sap_send(&emm_sap); - } + /* + * Notify ESM that all EPS bearer contexts allocated for this UE have + * to be locally deactivated + */ + esm_sap_t esm_sap; + esm_sap.primitive = ESM_EPS_BEARER_CONTEXT_DEACTIVATE_REQ; + esm_sap.ueid = ueid; + esm_sap.data.eps_bearer_context_deactivate.ebi = ESM_SAP_ALL_EBI; + rc = esm_sap_send(&esm_sap); + + if (rc != RETURNerror) { + emm_sap_t emm_sap; + /* + * Notify EMM that the UE has been implicitly detached + */ + emm_sap.primitive = EMMREG_DETACH_REQ; + emm_sap.u.emm_reg.ueid = ueid; + rc = emm_sap_send(&emm_sap); + } } LOG_FUNC_RETURN(rc); @@ -525,31 +537,31 @@ int emm_proc_detach_request(unsigned int ueid, emm_proc_detach_type_t type, #ifdef NAS_UE /* * -------------------------------------------------------------------------- - * Timer handlers + * Timer handlers * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _emm_detach_t3421_handler() ** + ** 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. ** + ** 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 ** + ** Inputs: args: handler parameters ** + ** Others: _emm_detach_data ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ -void* _emm_detach_t3421_handler(void* args) +void *_emm_detach_t3421_handler(void *args) { LOG_FUNC_IN; @@ -559,49 +571,47 @@ void* _emm_detach_t3421_handler(void* args) _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); + "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); @@ -609,22 +619,22 @@ void* _emm_detach_t3421_handler(void* args) /* * -------------------------------------------------------------------------- - * Abnormal cases in the UE + * Abnormal cases in the UE * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _emm_detach_abort() ** + ** Name: _emm_detach_abort() ** ** ** ** Description: Aborts the detach procedure ** ** ** - ** Inputs: type: not used ** - ** Others: _emm_detach_data ** + ** Inputs: type: not used ** + ** Others: _emm_detach_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3421 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3421 ** ** ** ***************************************************************************/ static int _emm_detach_abort(emm_proc_detach_type_t type) diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/EmmCommon.c b/openair-cn/NAS/EURECOM-NAS/src/emm/EmmCommon.c index ac49332d5e58a0c73c48e61bd57da322be75010c..4581dfbc175302c42fed787f5415591943ab9d07 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/EmmCommon.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/EmmCommon.c @@ -1,30 +1,30 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source EmmCommon.h +Source EmmCommon.h -Version 0.1 +Version 0.1 -Date 2013/04/19 +Date 2013/04/19 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines callback functions executed within EMM common procedures - by the Non-Access Stratum running at the network side. +Description Defines callback functions executed within EMM common procedures + by the Non-Access Stratum running at the network side. - Following EMM common procedures can always be initiated by the - network whilst a NAS signalling connection exists: + Following EMM common procedures can always be initiated by the + network whilst a NAS signalling connection exists: - GUTI reallocation - authentication - security mode control - identification - EMM information + GUTI reallocation + authentication + security mode control + identification + EMM information *****************************************************************************/ @@ -36,7 +36,7 @@ Description Defines callback functions executed within EMM common procedures #include "nas_log.h" #include "emmData.h" -#include <stdlib.h> // malloc, free +#include <stdlib.h> // malloc, free #include <string.h> #include <assert.h> @@ -52,10 +52,10 @@ Description Defines callback functions executed within EMM common procedures /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -/* EMM procedure callback cleanup function */ +/* EMM procedure callback cleanup function */ static void _emm_common_cleanup(unsigned int ueid); -/* Ongoing EMM procedure callback functions */ +/* Ongoing EMM procedure callback functions */ typedef struct emm_common_data_s { unsigned int ueid; int ref_count; @@ -63,7 +63,7 @@ typedef struct emm_common_data_s { emm_common_reject_callback_t reject; emm_common_failure_callback_t failure; emm_common_abort_callback_t abort; - void* args; + void *args; #if defined(EPC_BUILD) RB_ENTRY(emm_common_data_s) entries; @@ -117,7 +117,7 @@ struct emm_common_data_s *emm_common_data_context_get( return RB_FIND(emm_common_data_map, &root->emm_common_data_root, &reference); } #else -static emm_common_data_t* _emm_common_data[EMM_DATA_NB_UE_MAX]; +static emm_common_data_t *_emm_common_data[EMM_DATA_NB_UE_MAX]; #endif /****************************************************************************/ @@ -126,34 +126,34 @@ static emm_common_data_t* _emm_common_data[EMM_DATA_NB_UE_MAX]; /**************************************************************************** ** ** - ** Name: emm_proc_common_initialize() ** + ** Name: emm_proc_common_initialize() ** ** ** ** Description: Initialize EMM procedure callback functions executed for ** - ** the UE with the given identifier ** - ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** success: EMM procedure executed upon successful EMM ** - ** common procedure completion ** - ** reject: EMM procedure executed if the EMM common ** - ** procedure failed or is rejected ** - ** failure: EMM procedure executed upon transmission ** - ** failure reported by lower layer ** - ** abort: EMM common procedure executed when the on- ** - ** going EMM procedure is aborted ** - ** args: EMM common procedure argument parameters ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_common_data ** + ** the UE with the given identifier ** + ** ** + ** Inputs: ueid: UE lower layer identifier ** + ** success: EMM procedure executed upon successful EMM ** + ** common procedure completion ** + ** reject: EMM procedure executed if the EMM common ** + ** procedure failed or is rejected ** + ** failure: EMM procedure executed upon transmission ** + ** failure reported by lower layer ** + ** abort: EMM common procedure executed when the on- ** + ** going EMM procedure is aborted ** + ** args: EMM common procedure argument parameters ** + ** Others: None ** + ** ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_common_data ** ** ** ***************************************************************************/ int emm_proc_common_initialize(unsigned int ueid, - emm_common_success_callback_t _success, - emm_common_reject_callback_t _reject, - emm_common_failure_callback_t _failure, - emm_common_abort_callback_t _abort, - void* args) + emm_common_success_callback_t _success, + emm_common_reject_callback_t _reject, + emm_common_failure_callback_t _failure, + emm_common_abort_callback_t _abort, + void *args) { struct emm_common_data_s *emm_common_data_ctx = NULL; LOG_FUNC_IN; @@ -166,7 +166,7 @@ int emm_proc_common_initialize(unsigned int ueid, #endif if (emm_common_data_ctx == NULL) { - emm_common_data_ctx = (emm_common_data_t*)malloc(sizeof(emm_common_data_t)); + emm_common_data_ctx = (emm_common_data_t *)malloc(sizeof(emm_common_data_t)); emm_common_data_ctx->ueid = ueid; #if defined(EPC_BUILD) RB_INSERT(emm_common_data_map, &emm_common_data_head.emm_common_data_root, @@ -191,19 +191,19 @@ int emm_proc_common_initialize(unsigned int ueid, /**************************************************************************** ** ** - ** Name: emm_proc_common_success() ** + ** Name: emm_proc_common_success() ** ** ** ** Description: The EMM common procedure initiated between the UE with ** - ** the specified identifier and the MME completed success- ** - ** fully. The network performs required actions related to ** - ** the ongoing EMM procedure. ** + ** the specified identifier and the MME completed success- ** + ** fully. The network performs required actions related to ** + ** the ongoing EMM procedure. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** Others: _emm_common_data, _emm_data ** + ** Inputs: ueid: UE lower layer identifier ** + ** Others: _emm_common_data, _emm_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_common_success(unsigned int ueid) @@ -244,19 +244,19 @@ int emm_proc_common_success(unsigned int ueid) /**************************************************************************** ** ** - ** Name: emm_proc_common_reject() ** + ** Name: emm_proc_common_reject() ** ** ** ** Description: The EMM common procedure initiated between the UE with ** - ** the specified identifier and the MME failed or has been ** - ** rejected. The network performs required actions related ** - ** to the ongoing EMM procedure. ** + ** the specified identifier and the MME failed or has been ** + ** rejected. The network performs required actions related ** + ** to the ongoing EMM procedure. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** Others: _emm_common_data, _emm_data ** + ** Inputs: ueid: UE lower layer identifier ** + ** Others: _emm_common_data, _emm_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_common_reject(unsigned int ueid) @@ -297,20 +297,20 @@ int emm_proc_common_reject(unsigned int ueid) /**************************************************************************** ** ** - ** Name: emm_proc_common_failure() ** + ** Name: emm_proc_common_failure() ** ** ** ** Description: The EMM common procedure has been initiated between the ** - ** UE with the specified identifier and the MME, and a lower ** - ** layer failure occurred before the EMM common procedure ** - ** being completed. The network performs required actions ** - ** related to the ongoing EMM procedure. ** + ** UE with the specified identifier and the MME, and a lower ** + ** layer failure occurred before the EMM common procedure ** + ** being completed. The network performs required actions ** + ** related to the ongoing EMM procedure. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** Others: _emm_common_data, _emm_data ** + ** Inputs: ueid: UE lower layer identifier ** + ** Others: _emm_common_data, _emm_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_common_failure(unsigned int ueid) @@ -350,19 +350,19 @@ int emm_proc_common_failure(unsigned int ueid) /**************************************************************************** ** ** - ** Name: emm_proc_common_abort() ** + ** Name: emm_proc_common_abort() ** ** ** ** Description: The ongoing EMM procedure has been aborted. The network ** - ** performs required actions related to the EMM common pro- ** - ** cedure previously initiated between the UE with the spe- ** - ** cified identifier and the MME. ** + ** performs required actions related to the EMM common pro- ** + ** cedure previously initiated between the UE with the spe- ** + ** cified identifier and the MME. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** Others: _emm_common_data ** + ** Inputs: ueid: UE lower layer identifier ** + ** Others: _emm_common_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_common_abort(unsigned int ueid) @@ -402,21 +402,21 @@ int emm_proc_common_abort(unsigned int ueid) /**************************************************************************** ** ** - ** Name: emm_proc_common_get_args() ** + ** Name: emm_proc_common_get_args() ** ** ** ** Description: Returns pointer to the EMM common procedure argument pa- ** - ** rameters allocated for the UE with the given identifier. ** + ** rameters allocated for the UE with the given identifier. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** Others: _emm_common_data ** + ** Inputs: ueid: UE lower layer identifier ** + ** Others: _emm_common_data ** ** ** - ** Outputs: None ** - ** Return: pointer to the EMM common procedure argu- ** - ** ment parameters ** - ** Others: None ** + ** Outputs: None ** + ** Return: pointer to the EMM common procedure argu- ** + ** ment parameters ** + ** Others: None ** ** ** ***************************************************************************/ -void* emm_proc_common_get_args(unsigned int ueid) +void *emm_proc_common_get_args(unsigned int ueid) { emm_common_data_t *emm_common_data_ctx = NULL; LOG_FUNC_IN; @@ -439,19 +439,19 @@ void* emm_proc_common_get_args(unsigned int ueid) /**************************************************************************** ** ** - ** Name: emm_proc_common_cleanup() ** + ** Name: emm_proc_common_cleanup() ** ** ** ** Description: Cleans EMM procedure callback functions upon completion ** - ** of an EMM common procedure previously initiated within an ** - ** EMM procedure currently in progress between the network ** - ** and the UE with the specified identifier. ** + ** of an EMM common procedure previously initiated within an ** + ** EMM procedure currently in progress between the network ** + ** and the UE with the specified identifier. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: _emm_common_data ** + ** Outputs: None ** + ** Return: None ** + ** Others: _emm_common_data ** ** ** ***************************************************************************/ static void _emm_common_cleanup(unsigned int ueid) @@ -469,7 +469,7 @@ static void _emm_common_cleanup(unsigned int ueid) if (emm_common_data_ctx) { emm_common_data_ctx->ref_count -= 1; if (emm_common_data_ctx->ref_count == 0) { - /* Release the callback functions */ + /* Release the callback functions */ #if defined(EPC_BUILD) RB_REMOVE(emm_common_data_map, &emm_common_data_head.emm_common_data_root, @@ -477,7 +477,7 @@ static void _emm_common_cleanup(unsigned int ueid) #endif free(emm_common_data_ctx); emm_common_data_ctx = NULL; - } + } } } #endif // NAS_MME diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/EmmCommon.h b/openair-cn/NAS/EURECOM-NAS/src/emm/EmmCommon.h index 33705285d8afb7b55103d21c2531ea99fea730cf..449b08f475802b5314f86548139bfd7905b7b2d1 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/EmmCommon.h +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/EmmCommon.h @@ -1,30 +1,30 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source EmmCommon.h +Source EmmCommon.h -Version 0.1 +Version 0.1 -Date 2013/04/19 +Date 2013/04/19 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines callback functions executed within EMM common procedures - by the Non-Access Stratum running at the network side. +Description Defines callback functions executed within EMM common procedures + by the Non-Access Stratum running at the network side. - Following EMM common procedures can always be initiated by the - network whilst a NAS signalling connection exists: + Following EMM common procedures can always be initiated by the + network whilst a NAS signalling connection exists: - GUTI reallocation - authentication - security mode control - identification - EMM information + GUTI reallocation + authentication + security mode control + identification + EMM information *****************************************************************************/ #ifndef __EMM_COMMON_H__ @@ -47,9 +47,9 @@ Description Defines callback functions executed within EMM common procedures * - The EMM common procedure failed or is rejected * - Lower layer failure occured before the EMM common procedure completion */ -typedef int (*emm_common_success_callback_t)(void*); -typedef int (*emm_common_reject_callback_t) (void*); -typedef int (*emm_common_failure_callback_t)(void*); +typedef int (*emm_common_success_callback_t)(void *); +typedef int (*emm_common_reject_callback_t) (void *); +typedef int (*emm_common_failure_callback_t)(void *); /* * Type of EMM common procedure callback function @@ -57,7 +57,7 @@ typedef int (*emm_common_failure_callback_t)(void*); * EMM common procedure to be executed when the ongoing EMM procedure is * aborted. */ -typedef int (*emm_common_abort_callback_t)(void*); +typedef int (*emm_common_abort_callback_t)(void *); /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ @@ -68,17 +68,17 @@ typedef int (*emm_common_abort_callback_t)(void*); /****************************************************************************/ int emm_proc_common_initialize(unsigned int ueid, - emm_common_success_callback_t success, - emm_common_reject_callback_t reject, - emm_common_failure_callback_t failure, - emm_common_abort_callback_t abort, - void* args); + emm_common_success_callback_t success, + emm_common_reject_callback_t reject, + emm_common_failure_callback_t failure, + emm_common_abort_callback_t abort, + void *args); int emm_proc_common_success(unsigned int ueid); int emm_proc_common_reject(unsigned int ueid); int emm_proc_common_failure(unsigned int ueid); int emm_proc_common_abort(unsigned int ueid); -void* emm_proc_common_get_args(unsigned int ueid); +void *emm_proc_common_get_args(unsigned int ueid); #endif /* __EMM_COMMON_H__*/ diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/EmmStatusHdl.c b/openair-cn/NAS/EURECOM-NAS/src/emm/EmmStatusHdl.c index d6f52223da597db9bb08abb4256702b94ee38102..26595889055d8cc836955d251b0b54c878fbc453 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/EmmStatusHdl.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/EmmStatusHdl.c @@ -1,26 +1,26 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source Emmstatus.c +Source Emmstatus.c -Version 0.1 +Version 0.1 -Date 2013/06/26 +Date 2013/06/26 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines the EMM status procedure executed by the Non-Access - Stratum. +Description Defines the EMM status procedure executed by the Non-Access + Stratum. - The purpose of the sending of the EMM STATUS message is to - report at any time certain error conditions detected upon - receipt of EMM protocol data. The EMM STATUS message can be - sent by both the MME and the UE. + The purpose of the sending of the EMM STATUS message is to + report at any time certain error conditions detected upon + receipt of EMM protocol data. The EMM STATUS message can be + sent by both the MME and the UE. *****************************************************************************/ @@ -47,22 +47,22 @@ Description Defines the EMM status procedure executed by the Non-Access /**************************************************************************** ** ** - ** Name: emm_proc_status_ind() ** + ** Name: emm_proc_status_ind() ** ** ** ** Description: Processes received EMM status message. ** ** ** - ** 3GPP TS 24.301, section 5.7 ** - ** On receipt of an EMM STATUS message no state transition ** - ** and no specific action shall be taken. Local actions are ** - ** possible and are implementation dependent. ** + ** 3GPP TS 24.301, section 5.7 ** + ** On receipt of an EMM STATUS message no state transition ** + ** and no specific action shall be taken. Local actions are ** + ** possible and are implementation dependent. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** emm_cause: Received EMM cause code ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** emm_cause: Received EMM cause code ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_status_ind(unsigned int ueid, int emm_cause) @@ -72,7 +72,7 @@ int emm_proc_status_ind(unsigned int ueid, int emm_cause) int rc; LOG_TRACE(INFO,"EMM-PROC - EMM status procedure requested (cause=%d)", - emm_cause); + emm_cause); LOG_TRACE(DEBUG, "EMM-PROC - To be implemented"); @@ -84,17 +84,17 @@ int emm_proc_status_ind(unsigned int ueid, int emm_cause) /**************************************************************************** ** ** - ** Name: emm_proc_status() ** + ** Name: emm_proc_status() ** ** ** ** Description: Initiates EMM status procedure. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** emm_cause: EMM cause code to be reported ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** emm_cause: EMM cause code to be reported ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_status(unsigned int ueid, int emm_cause) @@ -133,7 +133,7 @@ int emm_proc_status(unsigned int ueid, int emm_cause) #endif /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.status.sctx, sctx, - FALSE, TRUE); + FALSE, TRUE); rc = emm_sap_send(&emm_sap); diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/Identification.c b/openair-cn/NAS/EURECOM-NAS/src/emm/Identification.c index c2ad0a52909331eb25f6f4529a8157db7954a07e..64715d7108aa99d90dd4172a6dd2487632cdecf1 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/Identification.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/Identification.c @@ -1,25 +1,25 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source Identification.c +Source Identification.c -Version 0.1 +Version 0.1 -Date 2013/04/09 +Date 2013/04/09 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines the identification EMM procedure executed by the - Non-Access Stratum. +Description Defines the identification EMM procedure executed by the + Non-Access Stratum. - The identification procedure is used by the network to request - a particular UE to provide specific identification parameters - (IMSI, IMEI). + The identification procedure is used by the network to request + a particular UE to provide specific identification parameters + (IMSI, IMEI). *****************************************************************************/ @@ -31,8 +31,8 @@ Description Defines the identification EMM procedure executed by the #include "emm_sap.h" -#include <stdlib.h> // malloc, free -#include <string.h> // memcpy +#include <stdlib.h> // malloc, free +#include <string.h> // memcpy /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -43,50 +43,50 @@ Description Defines the identification EMM procedure executed by the /****************************************************************************/ /* String representation of the requested identity type */ -static const char* _emm_identity_type_str[] = { +static const char *_emm_identity_type_str[] = { "NOT AVAILABLE", "IMSI", "IMEI", "IMEISV", "TMSI" }; /* * -------------------------------------------------------------------------- - * Internal data handled by the identification procedure in the UE + * Internal data handled by the identification procedure in the UE * -------------------------------------------------------------------------- */ #ifdef NAS_UE -#endif // NAS_UE +#endif // NAS_UE /* * -------------------------------------------------------------------------- - * Internal data handled by the identification procedure in the MME + * Internal data handled by the identification procedure in the MME * -------------------------------------------------------------------------- */ #ifdef NAS_MME /* * Timer handlers */ -static void* _identification_t3470_handler(void*); +static void *_identification_t3470_handler(void *); /* * Function executed whenever the ongoing EMM procedure that initiated * the identification procedure is aborted or the maximum value of the * retransmission timer counter is exceed */ -static int _identification_abort(void*); +static int _identification_abort(void *); /* * Internal data used for identification procedure */ typedef struct { - unsigned int ueid; /* UE identifier */ -#define IDENTIFICATION_COUNTER_MAX 5 - unsigned int retransmission_count; /* Retransmission counter */ - emm_proc_identity_type_t type; /* Type of UE identity */ - int notify_failure; /* Indicates whether the identification - * procedure failure shall be notified - * to the ongoing EMM procedure */ + unsigned int ueid; /* UE identifier */ +#define IDENTIFICATION_COUNTER_MAX 5 + unsigned int retransmission_count; /* Retransmission counter */ + emm_proc_identity_type_t type; /* Type of UE identity */ + int notify_failure; /* Indicates whether the identification + * procedure failure shall be notified + * to the ongoing EMM procedure */ } identification_data_t; -static int _identification_request(identification_data_t* data); +static int _identification_request(identification_data_t *data); #endif // NAS_MME /****************************************************************************/ @@ -95,28 +95,28 @@ static int _identification_request(identification_data_t* data); /* * -------------------------------------------------------------------------- - * Identification procedure executed by the UE + * Identification procedure executed by the UE * -------------------------------------------------------------------------- */ #ifdef NAS_UE /**************************************************************************** ** ** - ** Name: emm_proc_identification_request() ** + ** Name: emm_proc_identification_request() ** ** ** ** Description: Performs the MME requested identification procedure. ** ** ** ** 3GPP TS 24.301, section 5.4.4.3 ** - ** Upon receiving the IDENTITY REQUEST message, the UE shall ** - ** send an IDENTITY RESPONSE message to the network. The ** - ** IDENTITY RESPONSE message shall contain the identifica- ** - ** tion parameters as requested by the network. ** + ** Upon receiving the IDENTITY REQUEST message, the UE shall ** + ** send an IDENTITY RESPONSE message to the network. The ** + ** IDENTITY RESPONSE message shall contain the identifica- ** + ** tion parameters as requested by the network. ** ** ** - ** Inputs: type: Type of the requested identity ** - ** Others: None ** + ** Inputs: type: Type of the requested identity ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_identification_request(emm_proc_identity_type_t type) @@ -127,48 +127,47 @@ int emm_proc_identification_request(emm_proc_identity_type_t type) emm_sap_t emm_sap; LOG_TRACE(INFO, "EMM-PROC - Identification requested type = %s (%d)", - _emm_identity_type_str[type], type); + _emm_identity_type_str[type], type); /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ rc = emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); if (rc != RETURNok) { - LOG_TRACE(WARNING, - "EMM-PROC - Failed to initialize EMM procedure handler"); - LOG_FUNC_RETURN (RETURNerror); + LOG_TRACE(WARNING, + "EMM-PROC - Failed to initialize EMM procedure handler"); + LOG_FUNC_RETURN (RETURNerror); } emm_sap.u.emm_as.u.security.identType = EMM_IDENT_TYPE_NOT_AVAILABLE; - switch (type) - { - case EMM_IDENT_TYPE_IMSI: - /* International Mobile Subscriber Identity is requested */ - if (_emm_data.imsi) { - emm_sap.u.emm_as.u.security.identType = EMM_IDENT_TYPE_IMSI; - emm_sap.u.emm_as.u.security.imsi = _emm_data.imsi; - } - break; - - case EMM_IDENT_TYPE_IMEI: - /* International Mobile Equipment Identity is requested */ - if (_emm_data.imei) { - emm_sap.u.emm_as.u.security.identType = EMM_IDENT_TYPE_IMEI; - emm_sap.u.emm_as.u.security.imei = _emm_data.imei; - } - break; - - case EMM_IDENT_TYPE_TMSI: - /* Temporary Mobile Subscriber Identity is requested */ - if (_emm_data.guti) { - emm_sap.u.emm_as.u.security.identType = EMM_IDENT_TYPE_TMSI; - emm_sap.u.emm_as.u.security.tmsi = _emm_data.guti->m_tmsi; - } - break; - - default: - /* Other identities are not available */ - break; + switch (type) { + case EMM_IDENT_TYPE_IMSI: + /* International Mobile Subscriber Identity is requested */ + if (_emm_data.imsi) { + emm_sap.u.emm_as.u.security.identType = EMM_IDENT_TYPE_IMSI; + emm_sap.u.emm_as.u.security.imsi = _emm_data.imsi; + } + break; + + case EMM_IDENT_TYPE_IMEI: + /* International Mobile Equipment Identity is requested */ + if (_emm_data.imei) { + emm_sap.u.emm_as.u.security.identType = EMM_IDENT_TYPE_IMEI; + emm_sap.u.emm_as.u.security.imei = _emm_data.imei; + } + break; + + case EMM_IDENT_TYPE_TMSI: + /* Temporary Mobile Subscriber Identity is requested */ + if (_emm_data.guti) { + emm_sap.u.emm_as.u.security.identType = EMM_IDENT_TYPE_TMSI; + emm_sap.u.emm_as.u.security.tmsi = _emm_data.guti->m_tmsi; + } + break; + + default: + /* Other identities are not available */ + break; } /* @@ -181,7 +180,7 @@ int emm_proc_identification_request(emm_proc_identity_type_t type) emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_IDENT; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, FALSE, TRUE); + _emm_data.security, FALSE, TRUE); rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN (rc); @@ -190,86 +189,86 @@ int emm_proc_identification_request(emm_proc_identity_type_t type) /* * -------------------------------------------------------------------------- - * Identification procedure executed by the MME + * Identification procedure executed by the MME * -------------------------------------------------------------------------- */ #ifdef NAS_MME /**************************************************************************** ** ** - ** Name: emm_proc_identification() ** + ** 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 comnpletes ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** 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 comnpletes ** + ** 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) + 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)", - _emm_identity_type_str[type], type); + _emm_identity_type_str[type], type); /* Allocate parameters of the retransmission timer callback */ - identification_data_t* data = - (identification_data_t*)malloc(sizeof(identification_data_t)); + 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 - */ - emm_sap_t emm_sap; - emm_sap.primitive = EMMREG_COMMON_PROC_REQ; - emm_sap.u.emm_reg.ueid = ueid; + /* 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 + */ + 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); - } + rc = emm_sap_send(&emm_sap); + } } LOG_FUNC_RETURN (rc); @@ -277,33 +276,33 @@ int emm_proc_identification(unsigned int ueid, /**************************************************************************** ** ** - ** Name: emm_proc_identification_complete() ** + ** Name: emm_proc_identification_complete() ** ** ** ** Description: Performs the identification completion procedure executed ** - ** by the network. ** + ** by the network. ** ** ** ** 3GPP TS 24.301, section 5.4.4.4 ** - ** Upon receiving the IDENTITY RESPONSE message, the MME ** - ** shall stop timer T3470. ** + ** Upon receiving the IDENTITY RESPONSE message, the MME ** + ** shall stop timer T3470. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** imsi: The IMSI received from the UE ** - ** imei: The IMEI received from the UE ** - ** tmsi: The TMSI received from the UE ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** imsi: The IMSI received from the UE ** + ** imei: The IMEI received from the UE ** + ** tmsi: The TMSI received from the UE ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, T3470 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data, T3470 ** ** ** ***************************************************************************/ -int emm_proc_identification_complete(unsigned int ueid, const imsi_t* imsi, - const imei_t* imei, UInt32_t* tmsi) +int emm_proc_identification_complete(unsigned int ueid, const imsi_t *imsi, + const imei_t *imei, UInt32_t *tmsi) { int rc = RETURNerror; emm_sap_t emm_sap; - emm_data_context_t* emm_ctx = NULL; + emm_data_context_t *emm_ctx = NULL; LOG_FUNC_IN; @@ -314,9 +313,11 @@ int emm_proc_identification_complete(unsigned int ueid, const imsi_t* imsi, T3470.id = nas_timer_stop(T3470.id); /* Release retransmission timer paramaters */ - identification_data_t* data = - (identification_data_t*)(emm_proc_common_get_args(ueid)); - if (data) free(data); + identification_data_t *data = + (identification_data_t *)(emm_proc_common_get_args(ueid)); + if (data) { + free(data); + } /* Get the UE context */ #if defined(EPC_BUILD) @@ -330,49 +331,46 @@ int emm_proc_identification_complete(unsigned int ueid, const imsi_t* imsi, #endif if (emm_ctx) { - if (imsi) { - /* Update the IMSI */ - if (emm_ctx->imsi == NULL) { - emm_ctx->imsi = (imsi_t*)malloc(sizeof(imsi_t)); - } - if (emm_ctx->imsi) { - memcpy(emm_ctx->imsi, imsi, sizeof(imsi_t)); - } - } - else if (imei) { - /* Update the IMEI */ - if (emm_ctx->imei == NULL) { - emm_ctx->imei = (imei_t*)malloc(sizeof(imei_t)); - } - if (emm_ctx->imei) { - memcpy(emm_ctx->imei, imei, sizeof(imei_t)); - } - } - else if (tmsi) { - /* Update the GUTI */ - if (emm_ctx->guti == NULL) { - emm_ctx->guti = (GUTI_t*)malloc(sizeof(GUTI_t)); - } - if (emm_ctx->guti) { - memcpy(&emm_ctx->guti->gummei, - &_emm_data.conf.gummei, sizeof(gummei_t)); - emm_ctx->guti->m_tmsi = *tmsi; - } - } - /* - * Notify EMM that the identification procedure successfully completed - */ - emm_sap.primitive = EMMREG_COMMON_PROC_CNF; - emm_sap.u.emm_reg.ueid = ueid; - emm_sap.u.emm_reg.u.common.is_attached = emm_ctx->is_attached; - } - else { - LOG_TRACE(ERROR, "EMM-PROC - No EMM context exists"); - /* - * Notify EMM that the identification procedure failed - */ - emm_sap.primitive = EMMREG_COMMON_PROC_REJ; - emm_sap.u.emm_reg.ueid = ueid; + if (imsi) { + /* Update the IMSI */ + if (emm_ctx->imsi == NULL) { + emm_ctx->imsi = (imsi_t *)malloc(sizeof(imsi_t)); + } + if (emm_ctx->imsi) { + memcpy(emm_ctx->imsi, imsi, sizeof(imsi_t)); + } + } else if (imei) { + /* Update the IMEI */ + if (emm_ctx->imei == NULL) { + emm_ctx->imei = (imei_t *)malloc(sizeof(imei_t)); + } + if (emm_ctx->imei) { + memcpy(emm_ctx->imei, imei, sizeof(imei_t)); + } + } else if (tmsi) { + /* Update the GUTI */ + if (emm_ctx->guti == NULL) { + emm_ctx->guti = (GUTI_t *)malloc(sizeof(GUTI_t)); + } + if (emm_ctx->guti) { + memcpy(&emm_ctx->guti->gummei, + &_emm_data.conf.gummei, sizeof(gummei_t)); + emm_ctx->guti->m_tmsi = *tmsi; + } + } + /* + * Notify EMM that the identification procedure successfully completed + */ + emm_sap.primitive = EMMREG_COMMON_PROC_CNF; + emm_sap.u.emm_reg.ueid = ueid; + emm_sap.u.emm_reg.u.common.is_attached = emm_ctx->is_attached; + } else { + LOG_TRACE(ERROR, "EMM-PROC - No EMM context exists"); + /* + * Notify EMM that the identification procedure failed + */ + emm_sap.primitive = EMMREG_COMMON_PROC_REJ; + emm_sap.u.emm_reg.ueid = ueid; } rc = emm_sap_send(&emm_sap); @@ -389,53 +387,52 @@ int emm_proc_identification_complete(unsigned int ueid, const imsi_t* imsi, #ifdef NAS_MME /* * -------------------------------------------------------------------------- - * Timer handlers + * Timer handlers * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _identification_t3470_handler() ** + ** Name: _identification_t3470_handler() ** ** ** ** Description: T3470 timeout handler ** - ** Upon T3470 timer expiration, the identification request ** - ** message is retransmitted and the timer restarted. When ** - ** retransmission counter is exceed, the MME shall abort the ** - ** identification procedure and any ongoing EMM procedure. ** + ** Upon T3470 timer expiration, the identification request ** + ** message is retransmitted and the timer restarted. When ** + ** retransmission counter is exceed, the MME shall abort the ** + ** identification procedure and any ongoing EMM procedure. ** ** ** ** 3GPP TS 24.301, section 5.4.4.6, case b ** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ -static void* _identification_t3470_handler(void* args) +static void *_identification_t3470_handler(void *args) { LOG_FUNC_IN; int rc; - identification_data_t* data = (identification_data_t*)(args); + identification_data_t *data = (identification_data_t *)(args); /* Increment the retransmission counter */ data->retransmission_count += 1; LOG_TRACE(WARNING, "EMM-PROC - T3470 timer expired, retransmission " - "counter = %d", data->retransmission_count); + "counter = %d", data->retransmission_count); if (data->retransmission_count < IDENTIFICATION_COUNTER_MAX) { - /* Send identity request message to the UE */ - rc = _identification_request(data); - } - else { - /* Set the failure notification indicator */ - data->notify_failure = TRUE; - /* Abort the identification procedure */ - rc = _identification_abort(data); + /* Send identity request message to the UE */ + rc = _identification_request(data); + } else { + /* Set the failure notification indicator */ + data->notify_failure = TRUE; + /* Abort the identification procedure */ + rc = _identification_abort(data); } LOG_FUNC_RETURN (NULL); @@ -443,25 +440,25 @@ static void* _identification_t3470_handler(void* args) /* * -------------------------------------------------------------------------- - * MME specific local functions + * MME specific local functions * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _identification_request() ** + ** Name: _identification_request() ** ** ** ** Description: Sends IDENTITY REQUEST message and start timer T3470. ** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: T3470 ** + ** Outputs: None ** + ** Return: None ** + ** Others: T3470 ** ** ** ***************************************************************************/ -int _identification_request(identification_data_t* data) +int _identification_request(identification_data_t *data) { emm_sap_t emm_sap; int rc; @@ -495,16 +492,16 @@ int _identification_request(identification_data_t* data) rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { - if (T3470.id != NAS_TIMER_INACTIVE_ID) { - /* Re-start T3470 timer */ - T3470.id = nas_timer_restart(T3470.id); - } else { - /* Start T3470 timer */ - T3470.id = nas_timer_start(T3470.sec, _identification_t3470_handler, - data); - } - LOG_TRACE(INFO,"EMM-PROC - Timer T3470 (%d) expires in %ld seconds", - T3470.id, T3470.sec); + if (T3470.id != NAS_TIMER_INACTIVE_ID) { + /* Re-start T3470 timer */ + T3470.id = nas_timer_restart(T3470.id); + } else { + /* Start T3470 timer */ + T3470.id = nas_timer_start(T3470.sec, _identification_t3470_handler, + data); + } + LOG_TRACE(INFO,"EMM-PROC - Timer T3470 (%d) expires in %ld seconds", + T3470.id, T3470.sec); } LOG_FUNC_RETURN (rc); @@ -512,53 +509,52 @@ int _identification_request(identification_data_t* data) /**************************************************************************** ** ** - ** Name: _identification_abort() ** + ** Name: _identification_abort() ** ** ** ** Description: Aborts the identification procedure currently in progress ** ** ** - ** Inputs: args: Identification data to be released ** - ** Others: None ** + ** Inputs: args: Identification data to be released ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: T3470 ** + ** Outputs: None ** + ** Return: None ** + ** Others: T3470 ** ** ** ***************************************************************************/ -static int _identification_abort(void* args) +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; - } + 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); diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/IdleMode.c b/openair-cn/NAS/EURECOM-NAS/src/emm/IdleMode.c index 63ce97bc7ec603698f32e11e3e532241c005914e..c22c284f3bbeb8c5b1a5281166780b1ba5eac0a7 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/IdleMode.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/IdleMode.c @@ -1,40 +1,40 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source IdleMode.c +Source IdleMode.c -Version 0.1 +Version 0.1 -Date 2012/10/18 +Date 2012/10/18 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines EMM procedures executed by the Non-Access Stratum - when the UE is in idle mode. +Description Defines EMM procedures executed by the Non-Access Stratum + when the UE is in idle mode. - When a UE is switched on, a Public Land Mobile Network is - selected and the UE searches for a suitable cell of this PLMN - to camp on. The UE will, if necessary, register its presence - in the registration area of the chosen cell and as outcome of - a successful Location Registration the selected PLMN becomes - the registered PLMN. + When a UE is switched on, a Public Land Mobile Network is + selected and the UE searches for a suitable cell of this PLMN + to camp on. The UE will, if necessary, register its presence + in the registration area of the chosen cell and as outcome of + a successful Location Registration the selected PLMN becomes + the registered PLMN. - If the UE loses coverage of the registered PLMN, either a new - PLMN is selected automatically (automatic mode), or an indi- - cation of which PLMNs are available is given to the user, so - that a manual selection can be made (manual mode). + If the UE loses coverage of the registered PLMN, either a new + PLMN is selected automatically (automatic mode), or an indi- + cation of which PLMNs are available is given to the user, so + that a manual selection can be made (manual mode). - If the UE is unable to find a suitable cell to camp on, or - the USIM is not inserted, or if the location registration - failed under certain conditions, it attempts to camp on a - cell irrespective of the PLMN identity, and enters a "limited - service" state in which it can only attempt to make emergency - calls. + If the UE is unable to find a suitable cell to camp on, or + the USIM is not inserted, or if the location registration + failed under certain conditions, it attempts to camp on a + cell irrespective of the PLMN identity, and enters a "limited + service" state in which it can only attempt to make emergency + calls. *****************************************************************************/ @@ -60,8 +60,8 @@ Description Defines EMM procedures executed by the Non-Access Stratum /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -static int _IdleMode_plmn_str(char* plmn_str, const plmn_t* plmn); -static int _IldlMode_get_opnn_id(const plmn_t* plmn); +static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn); +static int _IldlMode_get_opnn_id(const plmn_t *plmn); static int _IdleMode_get_suitable_cell(int index); /* @@ -92,23 +92,23 @@ static int _IdleMode_get_suitable_cell(int index); */ static struct { int n_plmns; -#define EMM_PLMN_LIST_SIZE (EMM_DATA_EPLMN_MAX + EMM_DATA_PLMN_MAX + \ - EMM_DATA_OPLMN_MAX + 2) - plmn_t* plmn[EMM_PLMN_LIST_SIZE]; - int index; /* Index of the PLMN for which selection is ongoing */ - int hplmn; /* Index of the home PLMN or the highest priority - * equivalent home PLMN */ - int fplmn; /* Index of the first forbidden PLMN */ - int splmn; /* Index of the currently selected PLMN */ - int rplmn; /* Index of the currently registered PLMN */ +#define EMM_PLMN_LIST_SIZE (EMM_DATA_EPLMN_MAX + EMM_DATA_PLMN_MAX + \ + EMM_DATA_OPLMN_MAX + 2) + plmn_t *plmn[EMM_PLMN_LIST_SIZE]; + int index; /* Index of the PLMN for which selection is ongoing */ + int hplmn; /* Index of the home PLMN or the highest priority + * equivalent home PLMN */ + int fplmn; /* Index of the first forbidden PLMN */ + int splmn; /* Index of the currently selected PLMN */ + int rplmn; /* Index of the currently registered PLMN */ struct plmn_param_t { - char fullname[NET_FORMAT_LONG_SIZE+1]; /* PLMN full identifier */ - char shortname[NET_FORMAT_SHORT_SIZE+1]; /* PLMN short identifier */ - char num[NET_FORMAT_NUM_SIZE+1]; /* PLMN numeric identifier */ - int stat; /* Indication of the PLMN availability */ - int tac; /* Location/Tracking Area Code */ - int ci; /* Serving cell identifier */ - int rat; /* Radio Access Technology supported by the serving cell */ + char fullname[NET_FORMAT_LONG_SIZE+1]; /* PLMN full identifier */ + char shortname[NET_FORMAT_SHORT_SIZE+1]; /* PLMN short identifier */ + char num[NET_FORMAT_NUM_SIZE+1]; /* PLMN numeric identifier */ + int stat; /* Indication of the PLMN availability */ + int tac; /* Location/Tracking Area Code */ + int ci; /* Serving cell identifier */ + int rat; /* Radio Access Technology supported by the serving cell */ } param[EMM_PLMN_LIST_SIZE]; } _emm_plmn_list; @@ -121,18 +121,18 @@ static IdleMode_callback_t _emm_indication_notify; /**************************************************************************** ** ** - ** Name: IdleMode_initialize() ** + ** Name: IdleMode_initialize() ** ** ** ** Description: Initializes EMM internal data used when the UE operates ** - ** in idle mode ** + ** in idle mode ** ** ** - ** Inputs: cb: The function to executed whenever a net- ** - ** work indication is received ** - ** Others: None ** + ** Inputs: cb: The function to executed whenever a net- ** + ** work indication is received ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: _emm_plmn_list, _emm_indication_notify ** + ** Outputs: None ** + ** Return: None ** + ** Others: _emm_plmn_list, _emm_indication_notify ** ** ** ***************************************************************************/ void IdleMode_initialize(IdleMode_callback_t cb) @@ -160,17 +160,17 @@ void IdleMode_initialize(IdleMode_callback_t cb) /**************************************************************************** ** ** - ** Name: IdleMode_get_nb_plmns() ** + ** Name: IdleMode_get_nb_plmns() ** ** ** ** Description: Get the number of available PLMNs in the ordered list. ** ** ** - ** Inputs: None ** - ** Others: _emm_plmn_list ** + ** Inputs: None ** + ** Others: _emm_plmn_list ** ** ** - ** Outputs: None ** - ** Return: The number of PLMNs in the ordered list of ** - ** available PLMNs ** - ** Others: None ** + ** Outputs: None ** + ** Return: The number of PLMNs in the ordered list of ** + ** available PLMNs ** + ** Others: None ** ** ** ***************************************************************************/ int IdleMode_get_nb_plmns(void) @@ -180,18 +180,18 @@ int IdleMode_get_nb_plmns(void) /**************************************************************************** ** ** - ** Name: IdleMode_get_hplmn_index() ** + ** Name: IdleMode_get_hplmn_index() ** ** ** ** Description: Get the index of the Home PLMN or the highest priority ** - ** Equivalent HPLMN in the ordered list of available PLMNs. ** + ** Equivalent HPLMN in the ordered list of available PLMNs. ** ** ** - ** Inputs: None ** - ** Others: _emm_plmn_list ** + ** Inputs: None ** + ** Others: _emm_plmn_list ** ** ** - ** Outputs: None ** - ** Return: The index of the HPLMN or the first EHPLMN ** - ** in the list ** - ** Others: None ** + ** Outputs: None ** + ** Return: The index of the HPLMN or the first EHPLMN ** + ** in the list ** + ** Others: None ** ** ** ***************************************************************************/ int IdleMode_get_hplmn_index(void) @@ -201,18 +201,18 @@ int IdleMode_get_hplmn_index(void) /**************************************************************************** ** ** - ** Name: IdleMode_get_rplmn_index() ** + ** Name: IdleMode_get_rplmn_index() ** ** ** ** Description: Get the index of the registered PLMN in the ordered list ** - ** of available PLMNs. ** + ** of available PLMNs. ** ** ** - ** Inputs: None ** - ** Others: _emm_plmn_list ** + ** Inputs: None ** + ** Others: _emm_plmn_list ** ** ** - ** Outputs: None ** - ** Return: The index of the registered PLMN in the ** - ** list ** - ** Others: None ** + ** Outputs: None ** + ** Return: The index of the registered PLMN in the ** + ** list ** + ** Others: None ** ** ** ***************************************************************************/ int IdleMode_get_rplmn_index(void) @@ -222,17 +222,17 @@ int IdleMode_get_rplmn_index(void) /**************************************************************************** ** ** - ** Name: IdleMode_get_splmn_index() ** + ** Name: IdleMode_get_splmn_index() ** ** ** ** Description: Get the index of the selected PLMN in the ordered list of ** - ** available PLMNs. ** + ** available PLMNs. ** ** ** - ** Inputs: None ** - ** Others: _emm_plmn_list ** + ** Inputs: None ** + ** Others: _emm_plmn_list ** ** ** - ** Outputs: None ** - ** Return: The index of the selected PLMN in the list ** - ** Others: None ** + ** Outputs: None ** + ** Return: The index of the selected PLMN in the list ** + ** Others: None ** ** ** ***************************************************************************/ int IdleMode_get_splmn_index(void) @@ -242,17 +242,17 @@ int IdleMode_get_splmn_index(void) /**************************************************************************** ** ** - ** Name: IdleMode_update_plmn_list() ** + ** Name: IdleMode_update_plmn_list() ** ** ** ** Description: Updates the string representation of the list of opera- ** - ** tors present in the network ** + ** tors present in the network ** ** ** - ** Inputs: i: Index of the first operator to update ** - ** Others: _emm_plmn_list ** + ** Inputs: i: Index of the first operator to update ** + ** Others: _emm_plmn_list ** ** ** - ** Outputs: None ** - ** Return: The size of the list in bytes ** - ** Others: _emm_data.plist ** + ** Outputs: None ** + ** Return: The size of the list in bytes ** + ** Others: _emm_data.plist ** ** ** ***************************************************************************/ int IdleMode_update_plmn_list(int i) @@ -260,24 +260,23 @@ int IdleMode_update_plmn_list(int i) int offset = 0; int n = 1; - while ( (i < _emm_plmn_list.n_plmns) && (offset < EMM_DATA_BUFFER_SIZE) ) - { - struct plmn_param_t* plmn = &(_emm_plmn_list.param[i++]); - if (n++ > 1) { - offset += snprintf(_emm_data.plist.buffer + offset, - EMM_DATA_BUFFER_SIZE - offset, ","); - } - offset += snprintf(_emm_data.plist.buffer + offset, - EMM_DATA_BUFFER_SIZE - offset, "(%d,%s,%s,%s", - plmn->stat, plmn->fullname, - plmn->shortname, plmn->num); - if (plmn->rat != NET_ACCESS_UNAVAILABLE) { - offset += snprintf(_emm_data.plist.buffer + offset, - EMM_DATA_BUFFER_SIZE - offset, ",%d", - plmn->rat); - } - offset += snprintf(_emm_data.plist.buffer + offset, - EMM_DATA_BUFFER_SIZE - offset, ")"); + while ( (i < _emm_plmn_list.n_plmns) && (offset < EMM_DATA_BUFFER_SIZE) ) { + struct plmn_param_t *plmn = &(_emm_plmn_list.param[i++]); + if (n++ > 1) { + offset += snprintf(_emm_data.plist.buffer + offset, + EMM_DATA_BUFFER_SIZE - offset, ","); + } + offset += snprintf(_emm_data.plist.buffer + offset, + EMM_DATA_BUFFER_SIZE - offset, "(%d,%s,%s,%s", + plmn->stat, plmn->fullname, + plmn->shortname, plmn->num); + if (plmn->rat != NET_ACCESS_UNAVAILABLE) { + offset += snprintf(_emm_data.plist.buffer + offset, + EMM_DATA_BUFFER_SIZE - offset, ",%d", + plmn->rat); + } + offset += snprintf(_emm_data.plist.buffer + offset, + EMM_DATA_BUFFER_SIZE - offset, ")"); } return (offset); @@ -285,195 +284,194 @@ int IdleMode_update_plmn_list(int i) /**************************************************************************** ** ** - ** Name: IdleMode_get_plmn_fullname() ** + ** Name: IdleMode_get_plmn_fullname() ** ** ** ** Description: Get the full name of the PLMN at the given index in the ** - ** ordered list of available PLMNs. ** + ** ordered list of available PLMNs. ** ** ** - ** Inputs: plmn: The PLMN of which the name is queried ** - ** index: The index of the PLMN in the ordered list ** - ** of available PLMNs ** - ** Others: _emm_plmn_list ** + ** Inputs: plmn: The PLMN of which the name is queried ** + ** index: The index of the PLMN in the ordered list ** + ** of available PLMNs ** + ** Others: _emm_plmn_list ** ** ** - ** Outputs: size: The length of the PLMN's name ** - ** Return: A pointer to the full name of the PLMN ** - ** Others: None ** + ** Outputs: size: The length of the PLMN's name ** + ** Return: A pointer to the full name of the PLMN ** + ** Others: None ** ** ** ***************************************************************************/ -const char* IdleMode_get_plmn_fullname(const plmn_t* plmn, int index, size_t* len) +const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, + size_t *len) { if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].fullname); - return _emm_plmn_list.param[index].fullname; + assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); + *len = strlen(_emm_plmn_list.param[index].fullname); + return _emm_plmn_list.param[index].fullname; } return NULL; } /**************************************************************************** ** ** - ** Name: IdleMode_get_plmn_shortname() ** + ** Name: IdleMode_get_plmn_shortname() ** ** ** ** Description: Get the short name of the PLMN at the given index in the ** - ** ordered list of available PLMNs. ** + ** ordered list of available PLMNs. ** ** ** - ** Inputs: plmn: The PLMN of which the name is queried ** - ** index: The index of the PLMN in the ordered list ** - ** of available PLMNs ** - ** Others: _emm_plmn_list ** + ** Inputs: plmn: The PLMN of which the name is queried ** + ** index: The index of the PLMN in the ordered list ** + ** of available PLMNs ** + ** Others: _emm_plmn_list ** ** ** - ** Outputs: size: The length of the PLMN's name ** - ** Return: A pointer to the short name of the PLMN ** - ** Others: None ** + ** Outputs: size: The length of the PLMN's name ** + ** Return: A pointer to the short name of the PLMN ** + ** Others: None ** ** ** ***************************************************************************/ -const char* IdleMode_get_plmn_shortname(const plmn_t* plmn, int index, size_t* len) +const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index, + size_t *len) { if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].shortname); - return _emm_plmn_list.param[index].shortname; + assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); + *len = strlen(_emm_plmn_list.param[index].shortname); + return _emm_plmn_list.param[index].shortname; } return NULL; } /**************************************************************************** ** ** - ** Name: IdleMode_get_plmn_id() ** + ** Name: IdleMode_get_plmn_id() ** ** ** ** Description: Get the numeric identifier of the PLMN at the given index ** - ** in the ordered list of available PLMNs. ** + ** in the ordered list of available PLMNs. ** ** ** - ** Inputs: plmn: The PLMN of which the name is queried ** - ** index: The index of the PLMN in the ordered list ** - ** of available PLMNs ** - ** Others: _emm_plmn_list ** + ** Inputs: plmn: The PLMN of which the name is queried ** + ** index: The index of the PLMN in the ordered list ** + ** of available PLMNs ** + ** Others: _emm_plmn_list ** ** ** - ** Outputs: size: The length of the PLMN's name ** - ** Return: A pointer to the numeric identifier of the ** - ** PLMN ** - ** Others: None ** + ** Outputs: size: The length of the PLMN's name ** + ** Return: A pointer to the numeric identifier of the ** + ** PLMN ** + ** Others: None ** ** ** ***************************************************************************/ -const char* IdleMode_get_plmn_id(const plmn_t* plmn, int index, size_t* len) +const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len) { if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].num); - return _emm_plmn_list.param[index].num; + assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); + *len = strlen(_emm_plmn_list.param[index].num); + return _emm_plmn_list.param[index].num; } return NULL; } /**************************************************************************** ** ** - ** Name: IdleMode_get_plmn_fullname_index() ** + ** Name: IdleMode_get_plmn_fullname_index() ** ** ** ** Description: Search the list of available PLMNs for the index of the ** - ** PLMN identifier given by the specified fullname ** + ** PLMN identifier given by the specified fullname ** ** ** - ** Inputs: plmn: The full name of the PLMN ** - ** Others: _emm_plmn_list ** + ** Inputs: plmn: The full name of the PLMN ** + ** Others: _emm_plmn_list ** ** ** - ** Outputs: None ** - ** Return: The index of the PLMN, if found in the ** - ** list of available PLMNs; -1 otherwise. ** - ** Others: None ** + ** Outputs: None ** + ** Return: The index of the PLMN, if found in the ** + ** list of available PLMNs; -1 otherwise. ** + ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_fullname_index(const char* plmn) +int IdleMode_get_plmn_fullname_index(const char *plmn) { /* Get the index of the PLMN identifier with specified full name */ - for (int index = 0; index < _emm_plmn_list.n_plmns; index++) - { - if ( strncmp(plmn, _emm_plmn_list.param[index].fullname, - NET_FORMAT_LONG_SIZE) != 0 ) { - continue; - } - return (index); + for (int index = 0; index < _emm_plmn_list.n_plmns; index++) { + if ( strncmp(plmn, _emm_plmn_list.param[index].fullname, + NET_FORMAT_LONG_SIZE) != 0 ) { + continue; + } + return (index); } return (-1); } /**************************************************************************** ** ** - ** Name: IdleMode_get_plmn_shortname_index() ** + ** Name: IdleMode_get_plmn_shortname_index() ** ** ** ** Description: Search the list of available PLMNs for the index of the ** - ** PLMN identifier given by the specified shortname ** + ** PLMN identifier given by the specified shortname ** ** ** - ** Inputs: plmn: The short name of the PLMN ** - ** Others: _emm_plmn_list ** + ** Inputs: plmn: The short name of the PLMN ** + ** Others: _emm_plmn_list ** ** ** - ** Outputs: None ** - ** Return: The index of the PLMN, if found in the ** - ** list of available PLMNs; -1 otherwise. ** - ** Others: None ** + ** Outputs: None ** + ** Return: The index of the PLMN, if found in the ** + ** list of available PLMNs; -1 otherwise. ** + ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_shortname_index(const char* plmn) +int IdleMode_get_plmn_shortname_index(const char *plmn) { /* Get the index of the PLMN identifier with specified short name */ - for (int index = 0; index < _emm_plmn_list.n_plmns; index++) - { - if ( !strncmp(plmn, _emm_plmn_list.param[index].shortname, - NET_FORMAT_SHORT_SIZE) ) { - continue; - } - return (index); + for (int index = 0; index < _emm_plmn_list.n_plmns; index++) { + if ( !strncmp(plmn, _emm_plmn_list.param[index].shortname, + NET_FORMAT_SHORT_SIZE) ) { + continue; + } + return (index); } return (-1); } /**************************************************************************** ** ** - ** Name: IdleMode_get_plmn_id_index() ** + ** Name: IdleMode_get_plmn_id_index() ** ** ** ** Description: Search the list of available PLMNs for the index of the ** - ** PLMN identifier given by the specified numeric identifier ** + ** PLMN identifier given by the specified numeric identifier ** ** ** - ** Inputs: plmn: The numeric identifier of the PLMN ** - ** Others: _emm_plmn_list ** + ** Inputs: plmn: The numeric identifier of the PLMN ** + ** Others: _emm_plmn_list ** ** ** - ** Outputs: None ** - ** Return: The index of the PLMN, if found in the ** - ** list of available PLMNs; -1 otherwise. ** - ** Others: None ** + ** Outputs: None ** + ** Return: The index of the PLMN, if found in the ** + ** list of available PLMNs; -1 otherwise. ** + ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_id_index(const char* plmn) +int IdleMode_get_plmn_id_index(const char *plmn) { /* Get the index of the PLMN identifier with specified numeric identifier */ - for (int index = 0; index < _emm_plmn_list.n_plmns; index++) - { - if ( !strncmp(plmn, _emm_plmn_list.param[index].num, - NET_FORMAT_LONG_SIZE) ) { - continue; - } - return (index); + for (int index = 0; index < _emm_plmn_list.n_plmns; index++) { + if ( !strncmp(plmn, _emm_plmn_list.param[index].num, + NET_FORMAT_LONG_SIZE) ) { + continue; + } + return (index); } return (-1); } /* *--------------------------------------------------------------------------- - * Idle mode EMM procedures + * Idle mode EMM procedures *--------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: emm_proc_initialize() ** + ** Name: emm_proc_initialize() ** ** ** ** Description: Initialize the ordered list of available PLMNs candidate ** - ** to PLMN selection procedure. ** + ** to PLMN selection procedure. ** ** ** - ** Inputs: None ** - ** Others: _emm_data ** + ** Inputs: None ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_plmn_list ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_plmn_list ** ** ** ***************************************************************************/ int emm_proc_initialize(void) @@ -484,89 +482,85 @@ int emm_proc_initialize(void) int rc; if (!_emm_data.usim_is_valid) { - /* The USIM application is not present or not valid */ - LOG_TRACE(WARNING, "EMM-IDLE - USIM is not valid"); - emm_sap.primitive = EMMREG_NO_IMSI; - } - else - { - /* The highest priority is given to either the "equivalent PLMNs" - * if available, or the last registered PLMN */ - if (_emm_data.nvdata.eplmn.n_plmns > 0) { - for (int i=0; i < _emm_data.nvdata.eplmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.nvdata.eplmn.plmn[i]; - } - } - else if ( PLMN_IS_VALID(_emm_data.nvdata.rplmn) ) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.nvdata.rplmn; - } - - /* Update the index of the HPLMN or EHPLM of highest priority. - * When switched on, the UE will try to automatically register - * to each previous PLMN within the ordered list of available - * PLMNs regardless of the network selection mode of operation */ - _emm_plmn_list.hplmn = _emm_plmn_list.n_plmns; - - /* Add the highest priority PLMN in the list of "equivalent HPLMNs" - if present and not empty, or the HPLMN derived from the IMSI */ - if (_emm_data.ehplmn.n_plmns > 0) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.ehplmn.plmn[0]; - } - else { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = &_emm_data.hplmn; - } - - /* Each PLMN/access technology combination in the "User - * Controlled PLMN Selector with Access Technology" */ - for (int i=0; i < _emm_data.plmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.plmn.plmn[i]; - } - - /* Each PLMN/access technology combination in the "Operator - * Controlled PLMN Selector with Access Technology" */ - for (int i=0; i < _emm_data.oplmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.oplmn.plmn[i]; - } - - /* Other PLMN/access technology combinations with received - * high quality signal in random order */ - - /* Other PLMN/access technology combinations in order of - * decreasing signal quality */ - - /* TODO: Schedule periodic network selection attemps (hpplmn timer) */ - - /* Initialize the PLMNs' parameters */ - for (int i=0; i < _emm_plmn_list.n_plmns; i++) { - struct plmn_param_t* plmn = &(_emm_plmn_list.param[i]); - int id = _IldlMode_get_opnn_id(_emm_plmn_list.plmn[i]); - if (id < 0) { - plmn->fullname[0] = '\0'; - plmn->shortname[0] = '\0'; - } else { - strncpy(plmn->fullname, _emm_data.opnn[id].fullname, - NET_FORMAT_LONG_SIZE); - strncpy(plmn->shortname, _emm_data.opnn[id].shortname, - NET_FORMAT_SHORT_SIZE); - } - (void)_IdleMode_plmn_str(plmn->num, _emm_plmn_list.plmn[i]); - plmn->stat = NET_OPER_UNKNOWN; - plmn->tac = 0; - plmn->ci = 0; - plmn->rat = NET_ACCESS_UNAVAILABLE; - } - - LOG_TRACE(INFO, "EMM-IDLE - %d PLMNs available for network selection", - _emm_plmn_list.n_plmns); - - /* Notify EMM that PLMN selection procedure has to be executed */ - emm_sap.primitive = EMMREG_REGISTER_REQ; - emm_sap.u.emm_reg.u.regist.index = 0; + /* The USIM application is not present or not valid */ + LOG_TRACE(WARNING, "EMM-IDLE - USIM is not valid"); + emm_sap.primitive = EMMREG_NO_IMSI; + } else { + /* The highest priority is given to either the "equivalent PLMNs" + * if available, or the last registered PLMN */ + if (_emm_data.nvdata.eplmn.n_plmns > 0) { + for (int i=0; i < _emm_data.nvdata.eplmn.n_plmns; i++) { + _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + &_emm_data.nvdata.eplmn.plmn[i]; + } + } else if ( PLMN_IS_VALID(_emm_data.nvdata.rplmn) ) { + _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + &_emm_data.nvdata.rplmn; + } + + /* Update the index of the HPLMN or EHPLM of highest priority. + * When switched on, the UE will try to automatically register + * to each previous PLMN within the ordered list of available + * PLMNs regardless of the network selection mode of operation */ + _emm_plmn_list.hplmn = _emm_plmn_list.n_plmns; + + /* Add the highest priority PLMN in the list of "equivalent HPLMNs" + if present and not empty, or the HPLMN derived from the IMSI */ + if (_emm_data.ehplmn.n_plmns > 0) { + _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + &_emm_data.ehplmn.plmn[0]; + } else { + _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = &_emm_data.hplmn; + } + + /* Each PLMN/access technology combination in the "User + * Controlled PLMN Selector with Access Technology" */ + for (int i=0; i < _emm_data.plmn.n_plmns; i++) { + _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + &_emm_data.plmn.plmn[i]; + } + + /* Each PLMN/access technology combination in the "Operator + * Controlled PLMN Selector with Access Technology" */ + for (int i=0; i < _emm_data.oplmn.n_plmns; i++) { + _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + &_emm_data.oplmn.plmn[i]; + } + + /* Other PLMN/access technology combinations with received + * high quality signal in random order */ + + /* Other PLMN/access technology combinations in order of + * decreasing signal quality */ + + /* TODO: Schedule periodic network selection attemps (hpplmn timer) */ + + /* Initialize the PLMNs' parameters */ + for (int i=0; i < _emm_plmn_list.n_plmns; i++) { + struct plmn_param_t *plmn = &(_emm_plmn_list.param[i]); + int id = _IldlMode_get_opnn_id(_emm_plmn_list.plmn[i]); + if (id < 0) { + plmn->fullname[0] = '\0'; + plmn->shortname[0] = '\0'; + } else { + strncpy(plmn->fullname, _emm_data.opnn[id].fullname, + NET_FORMAT_LONG_SIZE); + strncpy(plmn->shortname, _emm_data.opnn[id].shortname, + NET_FORMAT_SHORT_SIZE); + } + (void)_IdleMode_plmn_str(plmn->num, _emm_plmn_list.plmn[i]); + plmn->stat = NET_OPER_UNKNOWN; + plmn->tac = 0; + plmn->ci = 0; + plmn->rat = NET_ACCESS_UNAVAILABLE; + } + + LOG_TRACE(INFO, "EMM-IDLE - %d PLMNs available for network selection", + _emm_plmn_list.n_plmns); + + /* Notify EMM that PLMN selection procedure has to be executed */ + emm_sap.primitive = EMMREG_REGISTER_REQ; + emm_sap.u.emm_reg.u.regist.index = 0; } rc = emm_sap_send(&emm_sap); @@ -578,26 +572,26 @@ int emm_proc_initialize(void) /**************************************************************************** ** ** - ** Name: emm_proc_plmn_selection() ** + ** Name: emm_proc_plmn_selection() ** ** ** ** Description: Performs the network selection procedure when the UE is ** - ** swicthed on. ** + ** swicthed on. ** ** ** - ** The MS shall select the registered PLMN or equivalent ** - ** PLMN (if it is available) using all access technologies ** - ** that the MS is capable. ** - ** If there is no registered PLMN, or if registration is ** - ** not possible due to the PLMN being unavailable or regis- ** - ** tration failure, the MS performs the automatic or the ma- ** - ** nual procedure depending on its PLMN selection operating ** - ** mode. ** + ** The MS shall select the registered PLMN or equivalent ** + ** PLMN (if it is available) using all access technologies ** + ** that the MS is capable. ** + ** If there is no registered PLMN, or if registration is ** + ** not possible due to the PLMN being unavailable or regis- ** + ** tration failure, the MS performs the automatic or the ma- ** + ** nual procedure depending on its PLMN selection operating ** + ** mode. ** ** ** - ** Inputs: None ** - ** Others: _emm_plmn_list, _emm_data ** + ** Inputs: None ** + ** Others: _emm_plmn_list, _emm_data ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: _emm_plmn_list.index ** + ** Outputs: None ** + ** Return: None ** + ** Others: _emm_plmn_list.index ** ** ** ***************************************************************************/ int emm_proc_plmn_selection(int index) @@ -607,45 +601,44 @@ int emm_proc_plmn_selection(int index) int rc = RETURNok; if (_emm_data.plmn_mode != EMM_DATA_PLMN_AUTO) { - /* - * Manual or manual/automatic mode of operation - * -------------------------------------------- - */ - if (index >= _emm_plmn_list.hplmn) { - /* - * Selection of the last registered or equivalent PLMNs failed - */ - if (_emm_data.plmn_index < 0) { - /* - * The user did not select any PLMN yet; display the ordered - * list of available PLMNs to the user - */ - index = -1; - rc = emm_proc_network_notify(_emm_plmn_list.hplmn); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify " - "network list update"); - } - } - else { - /* - * Try to register to the PLMN manually selected by the user - */ - index = _emm_data.plmn_index; - } - } + /* + * Manual or manual/automatic mode of operation + * -------------------------------------------- + */ + if (index >= _emm_plmn_list.hplmn) { + /* + * Selection of the last registered or equivalent PLMNs failed + */ + if (_emm_data.plmn_index < 0) { + /* + * The user did not select any PLMN yet; display the ordered + * list of available PLMNs to the user + */ + index = -1; + rc = emm_proc_network_notify(_emm_plmn_list.hplmn); + if (rc != RETURNok) { + LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify " + "network list update"); + } + } else { + /* + * Try to register to the PLMN manually selected by the user + */ + index = _emm_data.plmn_index; + } + } } if ( !(index < 0) ) { - /* - * Search for a suitable cell of the currently selected PLMN: - * It can be the last registered or one of the equivalent PLMNs - * if available, or the PLMN selected by the user in manual mode, - * or any other PLMN in the ordered list of available PLMNs in - * automatic mode. - */ - _emm_plmn_list.index = index; - rc = _IdleMode_get_suitable_cell(index); + /* + * Search for a suitable cell of the currently selected PLMN: + * It can be the last registered or one of the equivalent PLMNs + * if available, or the PLMN selected by the user in manual mode, + * or any other PLMN in the ordered list of available PLMNs in + * automatic mode. + */ + _emm_plmn_list.index = index; + rc = _IdleMode_get_suitable_cell(index); } LOG_FUNC_RETURN (rc); @@ -653,38 +646,38 @@ int emm_proc_plmn_selection(int index) /**************************************************************************** ** ** - ** Name: emm_proc_plmn_end() ** + ** Name: emm_proc_plmn_end() ** ** ** ** Description: Completes the network selection procedure or triggers a ** - ** new one until a suitable or acceptable cell of the chosen ** - ** PLMN is found. ** - ** ** - ** If a suitable cell of the selected PLMN has been found, ** - ** that cell is chosen to camp on and provide available ser- ** - ** vices, and tunes to its control channel. ** - ** The MS will then register its presence in the registra- ** - ** tion area of the chosen cell, if it is capable of servi- ** - ** ces which require registration. As outcome of a success- ** - ** ful Location Registration the selected PLMN becomes the ** - ** registered PLMN. ** + ** new one until a suitable or acceptable cell of the chosen ** + ** PLMN is found. ** + ** ** + ** If a suitable cell of the selected PLMN has been found, ** + ** that cell is chosen to camp on and provide available ser- ** + ** vices, and tunes to its control channel. ** + ** The MS will then register its presence in the registra- ** + ** tion area of the chosen cell, if it is capable of servi- ** + ** ces which require registration. As outcome of a success- ** + ** ful Location Registration the selected PLMN becomes the ** + ** registered PLMN. ** ** ** ** When no suitable cell can be found, the MS is unable to ** - ** obtain normal service from a PLMN. Then the MS attempts ** - ** to camp on an acceptable cell, irrespective of its PLMN ** - ** identity, so that only emergency calls can be made. ** - ** ** - ** Inputs: found: TRUE if a suitable cell of the chosen ** - ** PLMN has been found; FALSE otherwise. ** - ** tac: The code of the location/tracking area the ** - ** chosen PLMN belongs to ** - ** ci: The identifier of the cell ** - ** rat: The radio access technology supported by ** - ** the cell ** - ** Others: _emm_plmn_list, _emm_data ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: _emm_plmn_list, _emm_data ** + ** obtain normal service from a PLMN. Then the MS attempts ** + ** to camp on an acceptable cell, irrespective of its PLMN ** + ** identity, so that only emergency calls can be made. ** + ** ** + ** Inputs: found: TRUE if a suitable cell of the chosen ** + ** PLMN has been found; FALSE otherwise. ** + ** tac: The code of the location/tracking area the ** + ** chosen PLMN belongs to ** + ** ci: The identifier of the cell ** + ** rat: The radio access technology supported by ** + ** the cell ** + ** Others: _emm_plmn_list, _emm_data ** + ** ** + ** Outputs: None ** + ** Return: None ** + ** Others: _emm_plmn_list, _emm_data ** ** ** ***************************************************************************/ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) @@ -697,217 +690,212 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) int select_next_plmn = FALSE; LOG_TRACE(INFO, "EMM-IDLE - %s cell found for PLMN %d in %s mode", - (found)? "One" : "No", index, - (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : - (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : - "Automatic/manual"); - - if (found) - { - int is_forbidden = FALSE; - - /* Select the PLMN of which a suitable cell has been found */ - _emm_data.splmn = *_emm_plmn_list.plmn[index]; - - /* Update the selected PLMN's parameters */ - _emm_plmn_list.param[index].tac = tac; - _emm_plmn_list.param[index].ci = ci; - _emm_plmn_list.param[index].rat = rat; - - /* Update the location data and notify EMM that data have changed */ - rc = emm_proc_location_notify(tac, ci , rat); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify location update"); - } - - if (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO) { - /* - * Automatic mode of operation - * --------------------------- - */ - int i; - - /* Check if the selected PLMN is in the forbidden list */ - for (i = 0; i < _emm_data.fplmn.n_plmns; i++) { - if (PLMNS_ARE_EQUAL(_emm_data.splmn, _emm_data.fplmn.plmn[i])) { - is_forbidden = TRUE; - break; - } - } - if (!is_forbidden) { - for (i = 0; i < _emm_data.fplmn_gprs.n_plmns; i++) { - if (PLMNS_ARE_EQUAL(_emm_data.splmn, - _emm_data.fplmn_gprs.plmn[i])) { - is_forbidden = TRUE; - break; - } - } - } - /* Check if the selected PLMN belongs to a forbidden - * tracking area */ - tai_t tai; - tai.plmn = _emm_data.splmn; - tai.tac = tac; - if (!is_forbidden) { - for (i = 0; i < _emm_data.ftai.n_tais; i++) { - if (TAIS_ARE_EQUAL(tai, _emm_data.ftai.tai[i])) { - is_forbidden = TRUE; - break; - } - } - } - if (!is_forbidden) { - for (i = 0; i < _emm_data.ftai_roaming.n_tais; i++) { - if (TAIS_ARE_EQUAL(tai, _emm_data.ftai_roaming.tai[i])) { - is_forbidden = TRUE; - break; - } - } - } - } - - if (is_forbidden) { - /* The selected cell is known not to be able to provide normal - * service */ - LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this acceptable cell ", - "for limited services"); - - /* Save the index of the first forbidden PLMN */ - if (_emm_plmn_list.fplmn < 0) { - _emm_plmn_list.fplmn = index; - } - _emm_plmn_list.param[index].stat = NET_OPER_FORBIDDEN; - } - else { - /* A suitable cell has been found and the PLMN or tracking area - * is not in the forbidden list */ - LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this suitable cell ", - "for normal services"); - _emm_plmn_list.fplmn = -1; - _emm_plmn_list.param[index].stat = NET_OPER_CURRENT; - emm_sap.primitive = EMMREG_REGISTER_CNF; - } - - /* Duplicate the new selected PLMN at the end of the ordered list */ - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns] = &_emm_data.splmn; + (found)? "One" : "No", index, + (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : + (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : + "Automatic/manual"); + + if (found) { + int is_forbidden = FALSE; + + /* Select the PLMN of which a suitable cell has been found */ + _emm_data.splmn = *_emm_plmn_list.plmn[index]; + + /* Update the selected PLMN's parameters */ + _emm_plmn_list.param[index].tac = tac; + _emm_plmn_list.param[index].ci = ci; + _emm_plmn_list.param[index].rat = rat; + + /* Update the location data and notify EMM that data have changed */ + rc = emm_proc_location_notify(tac, ci , rat); + if (rc != RETURNok) { + LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify location update"); + } + + if (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO) { + /* + * Automatic mode of operation + * --------------------------- + */ + int i; + + /* Check if the selected PLMN is in the forbidden list */ + for (i = 0; i < _emm_data.fplmn.n_plmns; i++) { + if (PLMNS_ARE_EQUAL(_emm_data.splmn, _emm_data.fplmn.plmn[i])) { + is_forbidden = TRUE; + break; + } + } + if (!is_forbidden) { + for (i = 0; i < _emm_data.fplmn_gprs.n_plmns; i++) { + if (PLMNS_ARE_EQUAL(_emm_data.splmn, + _emm_data.fplmn_gprs.plmn[i])) { + is_forbidden = TRUE; + break; + } + } + } + /* Check if the selected PLMN belongs to a forbidden + * tracking area */ + tai_t tai; + tai.plmn = _emm_data.splmn; + tai.tac = tac; + if (!is_forbidden) { + for (i = 0; i < _emm_data.ftai.n_tais; i++) { + if (TAIS_ARE_EQUAL(tai, _emm_data.ftai.tai[i])) { + is_forbidden = TRUE; + break; + } + } + } + if (!is_forbidden) { + for (i = 0; i < _emm_data.ftai_roaming.n_tais; i++) { + if (TAIS_ARE_EQUAL(tai, _emm_data.ftai_roaming.tai[i])) { + is_forbidden = TRUE; + break; + } + } + } + } + + if (is_forbidden) { + /* The selected cell is known not to be able to provide normal + * service */ + LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this acceptable cell ", + "for limited services"); + + /* Save the index of the first forbidden PLMN */ + if (_emm_plmn_list.fplmn < 0) { + _emm_plmn_list.fplmn = index; + } + _emm_plmn_list.param[index].stat = NET_OPER_FORBIDDEN; + } else { + /* A suitable cell has been found and the PLMN or tracking area + * is not in the forbidden list */ + LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this suitable cell ", + "for normal services"); + _emm_plmn_list.fplmn = -1; + _emm_plmn_list.param[index].stat = NET_OPER_CURRENT; + emm_sap.primitive = EMMREG_REGISTER_CNF; + } + + /* Duplicate the new selected PLMN at the end of the ordered list */ + _emm_plmn_list.plmn[_emm_plmn_list.n_plmns] = &_emm_data.splmn; } else if (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO) { - /* - * Automatic mode of operation - * --------------------------- - * No suitable cell of the chosen PLMN has been found; - * Try to select the next PLMN in the ordered list of available PLMNs - */ - index += 1; - select_next_plmn = TRUE; - - /* Bypass the previously selected PLMN */ - if (index == _emm_plmn_list.splmn) { - index += 1; - } + /* + * Automatic mode of operation + * --------------------------- + * No suitable cell of the chosen PLMN has been found; + * Try to select the next PLMN in the ordered list of available PLMNs + */ + index += 1; + select_next_plmn = TRUE; + + /* Bypass the previously selected PLMN */ + if (index == _emm_plmn_list.splmn) { + index += 1; + } } else if (_emm_data.plmn_index < 0) { - /* - * Manual or manual/automatic mode of operation - * -------------------------------------------- - * Attempt to automatically find a suitable cell of the last - * registered or equivalent PLMNs is ongoing - */ - index += 1; - select_next_plmn = TRUE; - } + /* + * Manual or manual/automatic mode of operation + * -------------------------------------------- + * Attempt to automatically find a suitable cell of the last + * registered or equivalent PLMNs is ongoing + */ + index += 1; + select_next_plmn = TRUE; + } else if (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL) { - /* - * Manual mode of operation - * ------------------------ - * No suitable cell of the PLMN selected by the user has been found - */ - emm_sap.primitive = EMMREG_NO_CELL; + /* + * Manual mode of operation + * ------------------------ + * No suitable cell of the PLMN selected by the user has been found + */ + emm_sap.primitive = EMMREG_NO_CELL; } else { - /* - * Manual/automatic mode of operation - * -------------------------------------------- - * Attempt to find a suitable cell of the PLMN selected by the user - * failed; Try to automatically select another PLMN - */ - _emm_data.plmn_mode = EMM_DATA_PLMN_AUTO; - index = _emm_plmn_list.hplmn; - select_next_plmn = TRUE; + /* + * Manual/automatic mode of operation + * -------------------------------------------- + * Attempt to find a suitable cell of the PLMN selected by the user + * failed; Try to automatically select another PLMN + */ + _emm_data.plmn_mode = EMM_DATA_PLMN_AUTO; + index = _emm_plmn_list.hplmn; + select_next_plmn = TRUE; } /* * Force an attempt to register to the next PLMN */ if (select_next_plmn) { - int last_plmn_index = _emm_plmn_list.n_plmns; - if (_emm_plmn_list.splmn != -1) { - /* The last attempt was to register the previously selected PLMN */ - last_plmn_index += 1; - } - if (index < last_plmn_index) { - /* Try to select the next PLMN in the list of available PLMNs */ - _emm_plmn_list.index = index; - rc = emm_proc_plmn_selection(index); - } - else { - /* No suitable cell of any PLMN within the ordered list - * of available PLMNs has been found */ - select_next_plmn = FALSE; - emm_sap.primitive = EMMREG_NO_CELL; - } + int last_plmn_index = _emm_plmn_list.n_plmns; + if (_emm_plmn_list.splmn != -1) { + /* The last attempt was to register the previously selected PLMN */ + last_plmn_index += 1; + } + if (index < last_plmn_index) { + /* Try to select the next PLMN in the list of available PLMNs */ + _emm_plmn_list.index = index; + rc = emm_proc_plmn_selection(index); + } else { + /* No suitable cell of any PLMN within the ordered list + * of available PLMNs has been found */ + select_next_plmn = FALSE; + emm_sap.primitive = EMMREG_NO_CELL; + } } /* * Or terminate the PLMN selection procedure */ if (!select_next_plmn) { - if (!(_emm_plmn_list.fplmn) < 0) { - /* There were one or more PLMNs which were available and allowable, - * but an LR failure made registration on those PLMNs unsuccessful - * or an entry in any of the forbidden area lists prevented a - * registration attempt; select the first such PLMN and enters a - * limited service state. */ - index = _emm_plmn_list.fplmn; - _emm_plmn_list.fplmn = -1; - emm_sap.primitive = EMMREG_REGISTER_REJ; - } - /* Update the availability indicator of the previously selected PLMN */ - if (_emm_plmn_list.splmn != -1) { - _emm_plmn_list.param[_emm_plmn_list.splmn].stat = NET_OPER_UNKNOWN; - } - /* Update the index of the new selected PLMN */ - if (emm_sap.primitive != EMMREG_NO_CELL) { - _emm_plmn_list.splmn = index; - } - else { - _emm_plmn_list.splmn = -1; - } - /* - * Notify EMM that PLMN selection procedure has completed - */ - rc = emm_sap_send(&emm_sap); - - if (_emm_plmn_list.splmn != -1) { - if (_emm_plmn_list.splmn == _emm_plmn_list.rplmn) { - /* The selected PLMN is the registered PLMN */ - _emm_data.is_rplmn = TRUE; - } - else if (_emm_plmn_list.splmn < _emm_plmn_list.hplmn) { - /* The selected PLMN is in the list of equivalent PLMNs */ - _emm_data.is_eplmn = TRUE; - } - /* - * Notify EMM that an attach procedure has to be initiated - * to register the presence of the UE to the selected PLMN - */ - emm_sap.primitive = EMMREG_ATTACH_INIT; - rc = emm_sap_send(&emm_sap); - } + if (!(_emm_plmn_list.fplmn) < 0) { + /* There were one or more PLMNs which were available and allowable, + * but an LR failure made registration on those PLMNs unsuccessful + * or an entry in any of the forbidden area lists prevented a + * registration attempt; select the first such PLMN and enters a + * limited service state. */ + index = _emm_plmn_list.fplmn; + _emm_plmn_list.fplmn = -1; + emm_sap.primitive = EMMREG_REGISTER_REJ; + } + /* Update the availability indicator of the previously selected PLMN */ + if (_emm_plmn_list.splmn != -1) { + _emm_plmn_list.param[_emm_plmn_list.splmn].stat = NET_OPER_UNKNOWN; + } + /* Update the index of the new selected PLMN */ + if (emm_sap.primitive != EMMREG_NO_CELL) { + _emm_plmn_list.splmn = index; + } else { + _emm_plmn_list.splmn = -1; + } + /* + * Notify EMM that PLMN selection procedure has completed + */ + rc = emm_sap_send(&emm_sap); + + if (_emm_plmn_list.splmn != -1) { + if (_emm_plmn_list.splmn == _emm_plmn_list.rplmn) { + /* The selected PLMN is the registered PLMN */ + _emm_data.is_rplmn = TRUE; + } else if (_emm_plmn_list.splmn < _emm_plmn_list.hplmn) { + /* The selected PLMN is in the list of equivalent PLMNs */ + _emm_data.is_eplmn = TRUE; + } + /* + * Notify EMM that an attach procedure has to be initiated + * to register the presence of the UE to the selected PLMN + */ + emm_sap.primitive = EMMREG_ATTACH_INIT; + rc = emm_sap_send(&emm_sap); + } } LOG_FUNC_RETURN (rc); @@ -915,24 +903,24 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) /* *--------------------------------------------------------------------------- - * Network indication handlers + * Network indication handlers *--------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: emm_proc_registration_notify() ** + ** Name: emm_proc_registration_notify() ** ** ** ** Description: Updates the current network registration status and noti- ** - ** fy the EMM main controller that network registration sta- ** - ** tus has changed. ** + ** fy the EMM main controller that network registration sta- ** + ** tus has changed. ** ** ** - ** Inputs: status: The new network registraton status ** - ** Others: None ** + ** Inputs: status: The new network registraton status ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ int emm_proc_registration_notify(Stat_t status) @@ -943,9 +931,9 @@ int emm_proc_registration_notify(Stat_t status) /* Update the network registration status */ if (_emm_data.stat != status) { - _emm_data.stat = status; - /* Notify EMM that data has changed */ - rc = (*_emm_indication_notify)(1); + _emm_data.stat = status; + /* Notify EMM that data has changed */ + rc = (*_emm_indication_notify)(1); } LOG_FUNC_RETURN (rc); @@ -953,20 +941,20 @@ int emm_proc_registration_notify(Stat_t status) /**************************************************************************** ** ** - ** Name: emm_proc_location_notify() ** + ** Name: emm_proc_location_notify() ** ** ** ** Description: Updates the current location information and notify the ** - ** EMM main controller that location area has changed. ** + ** EMM main controller that location area has changed. ** ** ** - ** Inputs: tac: The code of the new location/tracking area ** - ** ci: The identifier of the new serving cell ** - ** rat: The Radio Access Technology supported by ** - ** the new serving cell ** - ** Others: None ** + ** Inputs: tac: The code of the new location/tracking area ** + ** ci: The identifier of the new serving cell ** + ** rat: The Radio Access Technology supported by ** + ** the new serving cell ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat) @@ -977,14 +965,13 @@ int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat) /* Update the location information */ if ( (_emm_data.tac != tac) || - (_emm_data.ci != ci) || - (_emm_data.rat != rat) ) - { - _emm_data.tac = tac; - _emm_data.ci = ci; - _emm_data.rat = rat; - /* Notify EMM that data has changed */ - rc = (*_emm_indication_notify)(0); + (_emm_data.ci != ci) || + (_emm_data.rat != rat) ) { + _emm_data.tac = tac; + _emm_data.ci = ci; + _emm_data.rat = rat; + /* Notify EMM that data has changed */ + rc = (*_emm_indication_notify)(0); } LOG_FUNC_RETURN (rc); @@ -992,19 +979,19 @@ int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat) /**************************************************************************** ** ** - ** Name: emm_proc_network_notify() ** + ** Name: emm_proc_network_notify() ** ** ** ** Description: Updates the string representation of the list of opera- ** - ** tors present in the network and notify the EMM main con- ** - ** troller that the list has to be displayed to the user ** - ** application. ** + ** tors present in the network and notify the EMM main con- ** + ** troller that the list has to be displayed to the user ** + ** application. ** ** ** - ** Inputs: index: Index of the first operator to update ** - ** Others: None ** + ** Inputs: index: Index of the first operator to update ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ int emm_proc_network_notify(int index) @@ -1028,65 +1015,89 @@ int emm_proc_network_notify(int index) #ifdef NAS_UE /**************************************************************************** ** ** - ** Name: _IdleMain_plmn_str() ** + ** Name: _IdleMain_plmn_str() ** ** ** ** Description: Converts a PLMN identifier to a string representation in ** - ** the numeric format ** + ** the numeric format ** ** ** - ** Inputs: plmn: The PLMN identifier to convert ** - ** Others: None ** + ** Inputs: plmn: The PLMN identifier to convert ** + ** Others: None ** ** ** - ** Outputs: plmn_str: The PLMN identifier in numeric format ** - ** Return: The size in bytes of the string represen- ** - ** tation of the PLMN identifier ** - ** Others: None ** + ** Outputs: plmn_str: The PLMN identifier in numeric format ** + ** Return: The size in bytes of the string represen- ** + ** tation of the PLMN identifier ** + ** Others: None ** ** ** ***************************************************************************/ -static int _IdleMode_plmn_str(char* plmn_str, const plmn_t* plmn) +static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn) { - char* p = plmn_str; + char *p = plmn_str; if (plmn == NULL) { - return 0; + return 0; } - if (plmn->MCCdigit1 != 0x0F) sprintf(p++, "%u", plmn->MCCdigit1); - if (plmn->MCCdigit2 != 0x0F) sprintf(p++, "%u", plmn->MCCdigit2); - if (plmn->MCCdigit3 != 0x0F) sprintf(p++, "%u", plmn->MCCdigit3); - if (plmn->MNCdigit1 != 0x0F) sprintf(p++, "%u", plmn->MNCdigit1); - if (plmn->MNCdigit2 != 0x0F) sprintf(p++, "%u", plmn->MNCdigit2); - if (plmn->MNCdigit3 != 0x0F) sprintf(p++, "%u", plmn->MNCdigit3); + if (plmn->MCCdigit1 != 0x0F) { + sprintf(p++, "%u", plmn->MCCdigit1); + } + if (plmn->MCCdigit2 != 0x0F) { + sprintf(p++, "%u", plmn->MCCdigit2); + } + if (plmn->MCCdigit3 != 0x0F) { + sprintf(p++, "%u", plmn->MCCdigit3); + } + if (plmn->MNCdigit1 != 0x0F) { + sprintf(p++, "%u", plmn->MNCdigit1); + } + if (plmn->MNCdigit2 != 0x0F) { + sprintf(p++, "%u", plmn->MNCdigit2); + } + if (plmn->MNCdigit3 != 0x0F) { + sprintf(p++, "%u", plmn->MNCdigit3); + } return (p - plmn_str); } /**************************************************************************** ** ** - ** Name: _IldlMode_get_opnn_id() ** + ** Name: _IldlMode_get_opnn_id() ** ** ** ** Description: Get the index of the specified PLMN in the list of opera- ** - ** tor network name records ** + ** tor network name records ** ** ** - ** Inputs: plmn: The PLMN identifier ** - ** Others: _emm_data ** + ** Inputs: plmn: The PLMN identifier ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: The index of the PLMN if found in the list ** - ** of operator network name records; ** - ** -1 otherwise; ** - ** Others: None ** + ** Outputs: None ** + ** Return: The index of the PLMN if found in the list ** + ** of operator network name records; ** + ** -1 otherwise; ** + ** Others: None ** ** ** ***************************************************************************/ -static int _IldlMode_get_opnn_id(const plmn_t* plmn) +static int _IldlMode_get_opnn_id(const plmn_t *plmn) { for (int i = 0; i < _emm_data.n_opnns; i++) { - if (plmn->MCCdigit1 != _emm_data.opnn[i].plmn->MCCdigit1) continue; - if (plmn->MCCdigit2 != _emm_data.opnn[i].plmn->MCCdigit2) continue; - if (plmn->MCCdigit3 != _emm_data.opnn[i].plmn->MCCdigit3) continue; - if (plmn->MNCdigit1 != _emm_data.opnn[i].plmn->MNCdigit1) continue; - if (plmn->MNCdigit2 != _emm_data.opnn[i].plmn->MNCdigit2) continue; - if (plmn->MNCdigit3 != _emm_data.opnn[i].plmn->MNCdigit3) continue; - /* Found */ - return (i); + if (plmn->MCCdigit1 != _emm_data.opnn[i].plmn->MCCdigit1) { + continue; + } + if (plmn->MCCdigit2 != _emm_data.opnn[i].plmn->MCCdigit2) { + continue; + } + if (plmn->MCCdigit3 != _emm_data.opnn[i].plmn->MCCdigit3) { + continue; + } + if (plmn->MNCdigit1 != _emm_data.opnn[i].plmn->MNCdigit1) { + continue; + } + if (plmn->MNCdigit2 != _emm_data.opnn[i].plmn->MNCdigit2) { + continue; + } + if (plmn->MNCdigit3 != _emm_data.opnn[i].plmn->MNCdigit3) { + continue; + } + /* Found */ + return (i); } /* Not found */ return (-1); @@ -1094,30 +1105,30 @@ static int _IldlMode_get_opnn_id(const plmn_t* plmn) /**************************************************************************** ** ** - ** Name: _IdleMode_get_suitable_cell() ** + ** Name: _IdleMode_get_suitable_cell() ** ** ** ** Description: Query the Access Stratum to search for a suitable cell ** - ** that belongs to the selected PLMN. ** + ** that belongs to the selected PLMN. ** ** ** - ** Inputs: index: Index of the selected PLMN in the ordered ** - ** list of available PLMNs ** - ** Others: _emm_plmn_list.plmn ** + ** Inputs: index: Index of the selected PLMN in the ordered ** + ** list of available PLMNs ** + ** Others: _emm_plmn_list.plmn ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ static int _IdleMode_get_suitable_cell(int index) { emm_sap_t emm_sap; - const plmn_t* plmn = _emm_plmn_list.plmn[index]; + const plmn_t *plmn = _emm_plmn_list.plmn[index]; LOG_TRACE(INFO, "EMM-IDLE - Trying to search a suitable cell " - "of PLMN %d in %s mode", index, - (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : - (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : - "Automatic/manual"); + "of PLMN %d in %s mode", index, + (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : + (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : + "Automatic/manual"); /* * Notify EMM-AS SAP that cell information related to the given * PLMN are requested from the Access-Stratum @@ -1126,9 +1137,9 @@ static int _IdleMode_get_suitable_cell(int index) emm_sap.u.emm_as.u.cell_info.plmnIDs.n_plmns = 1; emm_sap.u.emm_as.u.cell_info.plmnIDs.plmn[0] = *plmn; if (_emm_data.plmn_rat != NET_ACCESS_UNAVAILABLE) { - emm_sap.u.emm_as.u.cell_info.rat = (1 << _emm_data.plmn_rat); + emm_sap.u.emm_as.u.cell_info.rat = (1 << _emm_data.plmn_rat); } else { - emm_sap.u.emm_as.u.cell_info.rat = NET_ACCESS_UNAVAILABLE; + emm_sap.u.emm_as.u.cell_info.rat = NET_ACCESS_UNAVAILABLE; } return emm_sap_send(&emm_sap); diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/IdleMode.h b/openair-cn/NAS/EURECOM-NAS/src/emm/IdleMode.h index db1a51f032fa03ee1a072fb1504bfeddfbade039..0566291fbeb7965d9a4a2897a15f55e0920a9738 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/IdleMode.h +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/IdleMode.h @@ -1,22 +1,22 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source IdleMode.h +Source IdleMode.h -Version 0.1 +Version 0.1 -Date 2012/10/23 +Date 2012/10/23 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines the functions used to get information from the list - of available PLMNs locally maintained when the UE is in - idle mode. +Description Defines the functions used to get information from the list + of available PLMNs locally maintained when the UE is in + idle mode. *****************************************************************************/ #ifndef __IDLEMODE_H__ @@ -51,12 +51,14 @@ int IdleMode_get_splmn_index(void); int IdleMode_update_plmn_list(int index); -const char* IdleMode_get_plmn_fullname(const plmn_t* plmn, int index, size_t* len); -const char* IdleMode_get_plmn_shortname(const plmn_t* plmn, int index, size_t* len); -const char* IdleMode_get_plmn_id(const plmn_t* plmn, int index, size_t* len); +const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, + size_t *len); +const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index, + size_t *len); +const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len); -int IdleMode_get_plmn_fullname_index(const char* plmn); -int IdleMode_get_plmn_shortname_index(const char* plmn); -int IdleMode_get_plmn_id_index(const char* plmn); +int IdleMode_get_plmn_fullname_index(const char *plmn); +int IdleMode_get_plmn_shortname_index(const char *plmn); +int IdleMode_get_plmn_id_index(const char *plmn); #endif /* __IDLEMODE_H__*/ diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c b/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c index 7396e2bd57c904591d648a7cd5c4a0a556e7e355..4b0a779fbab0f7e0cc8f585eda69303dd449241b 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c @@ -1,24 +1,24 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source LowerLayer.c +Source LowerLayer.c -Version 0.1 +Version 0.1 -Date 2012/03/14 +Date 2012/03/14 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines EMM procedures executed by the Non-Access Stratum - upon receiving notifications from lower layers so that data - transfer succeed or failed, or NAS signalling connection is - released, or ESM unit data has been received from under layer, - and to request ESM unit data transfer to under layer. +Description Defines EMM procedures executed by the Non-Access Stratum + upon receiving notifications from lower layers so that data + transfer succeed or failed, or NAS signalling connection is + released, or ESM unit data has been received from under layer, + and to request ESM unit data transfer to under layer. *****************************************************************************/ @@ -31,7 +31,7 @@ Description Defines EMM procedures executed by the Non-Access Stratum #include "emm_sap.h" #include "esm_sap.h" -#include <string.h> // memset +#include <string.h> // memset /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -47,10 +47,10 @@ Description Defines EMM procedures executed by the Non-Access Stratum * receiving lower layer notifications */ static struct { - lowerlayer_success_callback_t success; /* Successful data delivery */ - lowerlayer_failure_callback_t failure; /* Lower layer failure */ - lowerlayer_release_callback_t release; /* NAS signalling release */ - void* args; /* EMM procedure argument parameters */ + lowerlayer_success_callback_t success; /* Successful data delivery */ + lowerlayer_failure_callback_t failure; /* Lower layer failure */ + lowerlayer_release_callback_t release; /* NAS signalling release */ + void *args; /* EMM procedure argument parameters */ } _lowerlayer_data; #endif @@ -60,23 +60,23 @@ static struct { /* * -------------------------------------------------------------------------- - * Lower layer notification handlers + * Lower layer notification handlers * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: lowerlayer_success() ** + ** Name: lowerlayer_success() ** ** ** ** Description: Notify the EPS Mobility Management entity that data have ** - ** been successfully delivered to the network ** + ** been successfully delivered to the network ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int lowerlayer_success(unsigned int ueid) @@ -95,17 +95,17 @@ int lowerlayer_success(unsigned int ueid) /**************************************************************************** ** ** - ** Name: lowerlayer_failure() ** + ** Name: lowerlayer_failure() ** ** ** ** Description: Notify the EPS Mobility Management entity that lower la- ** - ** yers failed to deliver data to the network ** + ** yers failed to deliver data to the network ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int lowerlayer_failure(unsigned int ueid) @@ -124,18 +124,18 @@ int lowerlayer_failure(unsigned int ueid) /**************************************************************************** ** ** - ** Name: lowerlayer_establish() ** + ** Name: lowerlayer_establish() ** ** ** ** Description: Update the EPS connection management status upon recei- ** - ** ving indication so that the NAS signalling connection is ** - ** established ** + ** ving indication so that the NAS signalling connection is ** + ** established ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int lowerlayer_establish(void) @@ -152,17 +152,17 @@ int lowerlayer_establish(void) /**************************************************************************** ** ** - ** Name: lowerlayer_release() ** + ** Name: lowerlayer_release() ** ** ** ** Description: Notify the EPS Mobility Management entity that NAS signal-** - ** ling connection has been released ** + ** ling connection has been released ** ** ** - ** Inputs: cause: Release cause ** - ** Others: None ** + ** Inputs: cause: Release cause ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int lowerlayer_release(int cause) @@ -186,21 +186,21 @@ int lowerlayer_release(int cause) /**************************************************************************** ** ** - ** Name: lowerlayer_data_ind() ** + ** Name: lowerlayer_data_ind() ** ** ** ** Description: Notify the EPS Session Management entity that data have ** - ** been received from lower layers ** + ** been received from lower layers ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** data: Data transfered from lower layers ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** data: Data transfered from lower layers ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_data_ind(unsigned int ueid, const OctetString* data) +int lowerlayer_data_ind(unsigned int ueid, const OctetString *data) { LOG_FUNC_IN; @@ -218,21 +218,21 @@ int lowerlayer_data_ind(unsigned int ueid, const OctetString* data) /**************************************************************************** ** ** - ** Name: lowerlayer_data_req() ** + ** Name: lowerlayer_data_req() ** ** ** ** Description: Notify the EPS Mobility Management entity that data have ** - ** to be transfered to lower layers ** + ** to be transfered to lower layers ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** data: Data to be transfered to lower layers ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** data: Data to be transfered to lower layers ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_data_req(unsigned int ueid, const OctetString* data) +int lowerlayer_data_req(unsigned int ueid, const OctetString *data) { LOG_FUNC_IN; @@ -275,35 +275,35 @@ int lowerlayer_data_req(unsigned int ueid, const OctetString* data) /* * -------------------------------------------------------------------------- - * EMM procedure handlers + * EMM procedure handlers * -------------------------------------------------------------------------- */ #ifdef NAS_UE /**************************************************************************** ** ** - ** Name: emm_proc_lowerlayer_initialize() ** + ** Name: emm_proc_lowerlayer_initialize() ** ** ** ** Description: Initialize EMM procedure handler ** ** ** - ** Inputs: success: EMM procedure executed when data have been ** - ** successfully delivered by lower layers ** - ** failure: EMM procedure executed upon transmission ** - ** failure reported by lower layers ** - ** release: EMM procedure executed when lower layers ** - ** report that NAS signalling connection has ** - ** been released ** - ** args: EMM procedure argument parameters ** - ** Others: None ** + ** Inputs: success: EMM procedure executed when data have been ** + ** successfully delivered by lower layers ** + ** failure: EMM procedure executed upon transmission ** + ** failure reported by lower layers ** + ** release: EMM procedure executed when lower layers ** + ** report that NAS signalling connection has ** + ** been released ** + ** args: EMM procedure argument parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _lowerlayer_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _lowerlayer_data ** ** ** ***************************************************************************/ int emm_proc_lowerlayer_initialize(lowerlayer_success_callback_t success, - lowerlayer_failure_callback_t failure, - lowerlayer_release_callback_t release, - void* args) + lowerlayer_failure_callback_t failure, + lowerlayer_release_callback_t release, + void *args) { LOG_FUNC_IN; @@ -317,18 +317,18 @@ int emm_proc_lowerlayer_initialize(lowerlayer_success_callback_t success, /**************************************************************************** ** ** - ** Name: emm_proc_lowerlayer_success() ** + ** Name: emm_proc_lowerlayer_success() ** ** ** ** Description: Handles EMM procedure to be executed upon receiving noti- ** - ** fication that data have been successfully delivered to ** - ** the network. ** + ** fication that data have been successfully delivered to ** + ** the network. ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_lowerlayer_success(void) @@ -340,8 +340,8 @@ int emm_proc_lowerlayer_success(void) lowerlayer_success_callback_t emm_callback = _lowerlayer_data.success; if (emm_callback) { - rc = (*emm_callback)(_lowerlayer_data.args); - _lowerlayer_data.success = NULL; + rc = (*emm_callback)(_lowerlayer_data.args); + _lowerlayer_data.success = NULL; } LOG_FUNC_RETURN (rc); @@ -349,18 +349,18 @@ int emm_proc_lowerlayer_success(void) /**************************************************************************** ** ** - ** Name: emm_proc_lowerlayer_failure() ** + ** Name: emm_proc_lowerlayer_failure() ** ** ** ** Description: Handles EMM procedure to be executed upon receiving noti- ** - ** fication that data failed to be delivered to the network. ** + ** fication that data failed to be delivered to the network. ** ** ** - ** Inputs: is_initial: TRUE if the NAS message that failed to be ** - ** transfered is an initial NAS message ** - ** Others: None ** + ** Inputs: is_initial: TRUE if the NAS message that failed to be ** + ** transfered is an initial NAS message ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_lowerlayer_failure(int is_initial) @@ -372,8 +372,8 @@ int emm_proc_lowerlayer_failure(int is_initial) lowerlayer_failure_callback_t emm_callback = _lowerlayer_data.failure; if (emm_callback) { - rc = (*emm_callback)(is_initial, _lowerlayer_data.args); - _lowerlayer_data.failure = NULL; + rc = (*emm_callback)(is_initial, _lowerlayer_data.args); + _lowerlayer_data.failure = NULL; } LOG_FUNC_RETURN (rc); @@ -381,17 +381,17 @@ int emm_proc_lowerlayer_failure(int is_initial) /**************************************************************************** ** ** - ** Name: emm_proc_lowerlayer_release() ** + ** Name: emm_proc_lowerlayer_release() ** ** ** ** Description: Handles EMM procedure to be executed upon receiving noti- ** - ** fication that NAS signalling connection has been released ** + ** fication that NAS signalling connection has been released ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_lowerlayer_release(void) @@ -403,8 +403,8 @@ int emm_proc_lowerlayer_release(void) lowerlayer_release_callback_t emm_callback = _lowerlayer_data.release; if (emm_callback) { - rc = (*emm_callback)(_lowerlayer_data.args); - _lowerlayer_data.release = NULL; + rc = (*emm_callback)(_lowerlayer_data.args); + _lowerlayer_data.release = NULL; } LOG_FUNC_RETURN (rc); @@ -413,60 +413,59 @@ int emm_proc_lowerlayer_release(void) /**************************************************************************** ** ** - ** Name: emm_as_set_security_data() ** + ** Name: emm_as_set_security_data() ** ** ** ** Description: Setup security data according to the given EPS security ** - ** context when data transfer to lower layers is requested ** + ** context when data transfer to lower layers is requested ** ** ** - ** Inputs: args: EPS security context currently in use ** - ** is_new: Indicates whether a new security context ** - ** has just been taken into use ** - ** is_ciphered: Indicates whether the NAS message has to ** - ** be sent ciphered ** - ** Others: None ** + ** Inputs: args: EPS security context currently in use ** + ** is_new: Indicates whether a new security context ** + ** has just been taken into use ** + ** is_ciphered: Indicates whether the NAS message has to ** + ** be sent ciphered ** + ** Others: None ** ** ** - ** Outputs: data: EPS NAS security data to be setup ** - ** Return: None ** - ** Others: None ** + ** Outputs: data: EPS NAS security data to be setup ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ -void emm_as_set_security_data(emm_as_security_data_t* data, const void* args, - int is_new, int is_ciphered) +void emm_as_set_security_data(emm_as_security_data_t *data, const void *args, + int is_new, int is_ciphered) { LOG_FUNC_IN; - const emm_security_context_t* context = (emm_security_context_t*)(args); + const emm_security_context_t *context = (emm_security_context_t *)(args); memset(data, 0, sizeof(emm_as_security_data_t)); if ( context && (context->type != EMM_KSI_NOT_AVAILABLE) ) { - /* 3GPP TS 24.301, sections 5.4.3.3 and 5.4.3.4 - * Once a valid EPS security context exists and has been taken - * into use, UE and MME shall cipher and integrity protect all - * NAS signalling messages with the selected NAS ciphering and - * NAS integrity algorithms */ - data->is_new = is_new; - data->ksi = context->eksi; - data->sqn = context->ul_count.seq_num; - data->count = *(UInt32_t*)(&context->ul_count); - /* NAS integrity and cyphering keys may not be available if the - * current security context is a partial EPS security context - * and not a full native EPS security context */ - data->k_int = &context->knas_int; - if (is_ciphered) { - /* 3GPP TS 24.301, sections 4.4.5 - * When the UE establishes a new NAS signalling connection, - * it shall send initial NAS messages integrity protected - * and unciphered */ - /* 3GPP TS 24.301, section 5.4.3.2 - * The MME shall send the SECURITY MODE COMMAND message integrity - * protected and unciphered */ - data->k_enc = &context->knas_enc; - } - } - else { - /* No valid EPS security context exists */ - data->ksi = EMM_AS_NO_KEY_AVAILABLE; + /* 3GPP TS 24.301, sections 5.4.3.3 and 5.4.3.4 + * Once a valid EPS security context exists and has been taken + * into use, UE and MME shall cipher and integrity protect all + * NAS signalling messages with the selected NAS ciphering and + * NAS integrity algorithms */ + data->is_new = is_new; + data->ksi = context->eksi; + data->sqn = context->ul_count.seq_num; + data->count = *(UInt32_t *)(&context->ul_count); + /* NAS integrity and cyphering keys may not be available if the + * current security context is a partial EPS security context + * and not a full native EPS security context */ + data->k_int = &context->knas_int; + if (is_ciphered) { + /* 3GPP TS 24.301, sections 4.4.5 + * When the UE establishes a new NAS signalling connection, + * it shall send initial NAS messages integrity protected + * and unciphered */ + /* 3GPP TS 24.301, section 5.4.3.2 + * The MME shall send the SECURITY MODE COMMAND message integrity + * protected and unciphered */ + data->k_enc = &context->knas_enc; + } + } else { + /* No valid EPS security context exists */ + data->ksi = EMM_AS_NO_KEY_AVAILABLE; } LOG_FUNC_OUT; diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.h b/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.h index 9aa715b9326dfd1e6c58df2426117f55b204111b..d83ec1e351650cd77282d1da56bd2744cb67c0be 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.h +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.h @@ -1,24 +1,24 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source lowerlayer.h +Source lowerlayer.h -Version 0.1 +Version 0.1 -Date 2013/06/19 +Date 2013/06/19 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines EMM procedures executed by the Non-Access Stratum - upon receiving notifications from lower layers so that data - transfer succeed or failed, or NAS signalling connection is - released, or ESM unit data has been received from under layer, - and to request ESM unit data transfer to under layer. +Description Defines EMM procedures executed by the Non-Access Stratum + upon receiving notifications from lower layers so that data + transfer succeed or failed, or NAS signalling connection is + released, or ESM unit data has been received from under layer, + and to request ESM unit data transfer to under layer. *****************************************************************************/ #ifndef __LOWERLAYER_H__ @@ -35,19 +35,19 @@ Description Defines EMM procedures executed by the Non-Access Stratum * Type of EMM procedure callback function executed whenever data are * successfully delivered to the network */ -typedef int (*lowerlayer_success_callback_t)(void*); +typedef int (*lowerlayer_success_callback_t)(void *); /* * Type of EMM procedure callback function executed when data are not * delivered to the network because a lower layer failure occurred */ -typedef int (*lowerlayer_failure_callback_t)(int, void*); +typedef int (*lowerlayer_failure_callback_t)(int, void *); /* * Type of EMM procedure callback function executed when NAS signalling * connection is released */ -typedef int (*lowerlayer_release_callback_t)(void*); +typedef int (*lowerlayer_release_callback_t)(void *); #endif /****************************************************************************/ @@ -67,7 +67,7 @@ int lowerlayer_failure(unsigned int ueid); int lowerlayer_establish(void); int lowerlayer_release(int cause); -int lowerlayer_data_ind(unsigned int ueid, const OctetString* data); -int lowerlayer_data_req(unsigned int ueid, const OctetString* data); +int lowerlayer_data_ind(unsigned int ueid, const OctetString *data); +int lowerlayer_data_req(unsigned int ueid, const OctetString *data); #endif /* __LOWERLAYER_H__*/ diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c b/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c index 292b317ccd6b9a3828c1f722c9d07e48259cbc3f..66f355b25ba0ecf1807e25f67a85097a1dddf512 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c @@ -1,30 +1,30 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source SecurityModeControl.c +Source SecurityModeControl.c -Version 0.1 +Version 0.1 -Date 2013/04/22 +Date 2013/04/22 -Product NAS stack +Product NAS stack -Subsystem Template body file +Subsystem Template body file -Author Frederic Maurel +Author Frederic Maurel -Description Defines the security mode control EMM procedure executed by the - Non-Access Stratum. +Description Defines the security mode control EMM procedure executed by the + Non-Access Stratum. - The purpose of the NAS security mode control procedure is to - take an EPS security context into use, and initialise and start - NAS signalling security between the UE and the MME with the - corresponding EPS NAS keys and EPS security algorithms. + The purpose of the NAS security mode control procedure is to + take an EPS security context into use, and initialise and start + NAS signalling security between the UE and the MME with the + corresponding EPS NAS keys and EPS security algorithms. - Furthermore, the network may also initiate a SECURITY MODE COM- - MAND in order to change the NAS security algorithms for a cur- - rent EPS security context already in use. + Furthermore, the network may also initiate a SECURITY MODE COM- + MAND in order to change the NAS security algorithms for a cur- + rent EPS security context already in use. *****************************************************************************/ @@ -37,8 +37,8 @@ Description Defines the security mode control EMM procedure executed by the #include "emm_sap.h" #include "emm_cause.h" -#include <stdlib.h> // malloc, free -#include <string.h> // memcpy +#include <stdlib.h> // malloc, free +#include <string.h> // memcpy /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -54,22 +54,25 @@ Description Defines the security mode control EMM procedure executed by the * -------------------------------------------------------------------------- */ #ifdef NAS_UE -static int _security_kdf(const OctetString* kasme, OctetString* key, - UInt8_t algo_dist, UInt8_t algo_id); +static int _security_kdf(const OctetString *kasme, OctetString *key, + UInt8_t algo_dist, UInt8_t algo_id); -static int _security_knas_enc(const OctetString* kasme, OctetString* knas_enc, UInt8_t eia); -static int _security_knas_int(const OctetString* kasme, OctetString* knas_int, UInt8_t eea); -static int _security_kenb(const OctetString* kasme, OctetString* kenb, UInt32_t count); +static int _security_knas_enc(const OctetString *kasme, OctetString *knas_enc, + UInt8_t eia); +static int _security_knas_int(const OctetString *kasme, OctetString *knas_int, + UInt8_t eea); +static int _security_kenb(const OctetString *kasme, OctetString *kenb, + UInt32_t count); /* * Internal data used for security mode control procedure */ static struct { - OctetString kenb; /* eNodeB security key */ + OctetString kenb; /* eNodeB security key */ } _security_data; -static void _security_release(emm_security_context_t* ctx); -#endif // NAS_UE +static void _security_release(emm_security_context_t *ctx); +#endif // NAS_UE /* * -------------------------------------------------------------------------- @@ -80,31 +83,31 @@ static void _security_release(emm_security_context_t* ctx); /* * Timer handlers */ -static void* _security_t3460_handler(void*); +static void *_security_t3460_handler(void *); /* * Function executed whenever the ongoing EMM procedure that initiated * the security mode control procedure is aborted or the maximum value of the * retransmission timer counter is exceed */ -static int _security_abort(void*); +static int _security_abort(void *); /* * Internal data used for security mode control procedure */ typedef struct { - unsigned int ueid; /* UE identifier */ -#define SECURITY_COUNTER_MAX 5 - unsigned int retransmission_count; /* Retransmission counter */ - int ksi; /* NAS key set identifier */ - int eea; /* Replayed EPS encryption algorithms */ - int eia; /* Replayed EPS integrity algorithms */ - int notify_failure; /* Indicates whether the security mode control - * procedure failure shall be notified to the - * ongoing EMM procedure */ + unsigned int ueid; /* UE identifier */ +#define SECURITY_COUNTER_MAX 5 + unsigned int retransmission_count; /* Retransmission counter */ + int ksi; /* NAS key set identifier */ + int eea; /* Replayed EPS encryption algorithms */ + int eia; /* Replayed EPS integrity algorithms */ + int notify_failure; /* Indicates whether the security mode control + * procedure failure shall be notified to the + * ongoing EMM procedure */ } security_data_t; -static int _security_request(security_data_t* data, int is_new); +static int _security_request(security_data_t *data, int is_new); #endif // NAS_MME /****************************************************************************/ @@ -113,41 +116,41 @@ static int _security_request(security_data_t* data, int is_new); /* * -------------------------------------------------------------------------- - * Security mode control procedure executed by the UE + * Security mode control procedure executed by the UE * -------------------------------------------------------------------------- */ #ifdef NAS_UE /**************************************************************************** ** ** - ** Name: emm_proc_security_mode_command() ** + ** Name: emm_proc_security_mode_command() ** ** ** ** Description: Performs the MME requested security mode control proce- ** - ** dure. ** + ** dure. ** ** ** ** 3GPP TS 24.301, section 5.4.3.3 ** - ** Upon receiving the SECURITY MODE COMMAND message, the UE ** - ** shall check whether the message can be accepted or not. ** - ** If accepted the UE shall send a SECURITY MODE COMPLETE ** - ** message integrity protected with the selected NAS inte- ** - ** grity algorithm and ciphered with the selected NAS ciphe- ** - ** ring algorithm. ** - ** ** - ** Inputs: native_ksi: TRUE if the security context is of type ** - ** native (for KSIASME) ** - ** ksi: The NAS ket sey identifier ** - ** seea: Selected EPS cyphering algorithm ** - ** seia: Selected EPS integrity algorithm ** - ** reea: Replayed EPS cyphering algorithm ** - ** reia: Replayed EPS integrity algorithm ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Upon receiving the SECURITY MODE COMMAND message, the UE ** + ** shall check whether the message can be accepted or not. ** + ** If accepted the UE shall send a SECURITY MODE COMPLETE ** + ** message integrity protected with the selected NAS inte- ** + ** grity algorithm and ciphered with the selected NAS ciphe- ** + ** ring algorithm. ** + ** ** + ** Inputs: native_ksi: TRUE if the security context is of type ** + ** native (for KSIASME) ** + ** ksi: The NAS ket sey identifier ** + ** seea: Selected EPS cyphering algorithm ** + ** seia: Selected EPS integrity algorithm ** + ** reea: Replayed EPS cyphering algorithm ** + ** reia: Replayed EPS integrity algorithm ** + ** Others: None ** + ** ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_security_mode_command(int native_ksi, int ksi, - int seea, int seia, int reea, int reia) + int seea, int seia, int reea, int reia) { LOG_FUNC_IN; @@ -156,7 +159,7 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, int security_context_is_new = FALSE; LOG_TRACE(INFO, "EMM-PROC - Security mode control requested (ksi=%d)", - ksi); + ksi); /* Delete any previously stored RAND and RES and stop timer T3416 */ (void) emm_proc_authentication_delete(); @@ -167,134 +170,134 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, UInt8_t eea = (0x80 >> _emm_data.security->capability.encryption); UInt8_t eia = (0x80 >> _emm_data.security->capability.integrity); if ( (reea != eea) || (reia != eia) ) { - LOG_TRACE(WARNING, "EMM-PROC - Replayed UE security capabilities " - "rejected"); - emm_cause = EMM_CAUSE_UE_SECURITY_MISMATCH; - - /* XXX - For testing purpose UE always accepts EIA0 - * The UE shall accept "null integrity protection algorithm" EIA0 only - * if a PDN connection for emergency bearer services is established or - * the UE is establishing a PDN connection for emergency bearer services - */ + LOG_TRACE(WARNING, "EMM-PROC - Replayed UE security capabilities " + "rejected"); + emm_cause = EMM_CAUSE_UE_SECURITY_MISMATCH; + + /* XXX - For testing purpose UE always accepts EIA0 + * The UE shall accept "null integrity protection algorithm" EIA0 only + * if a PDN connection for emergency bearer services is established or + * the UE is establishing a PDN connection for emergency bearer services + */ } /* * Check the non-current EPS security context */ else if (_emm_data.non_current == NULL) { - LOG_TRACE(WARNING, "EMM-PROC - Non-current EPS security context " - "is not valid"); - emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED; + LOG_TRACE(WARNING, "EMM-PROC - Non-current EPS security context " + "is not valid"); + emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED; } /* * Update the non-current EPS security context */ else { - /* Update selected cyphering and integrity algorithms */ - _emm_data.non_current->capability.encryption = seea; - _emm_data.non_current->capability.integrity = seia; - - /* Derive the NAS cyphering key */ - if (_emm_data.non_current->knas_enc.value == NULL) { - _emm_data.non_current->knas_enc.value = - (uint8_t*)malloc(AUTH_KNAS_ENC_SIZE); - _emm_data.non_current->knas_enc.length = AUTH_KNAS_ENC_SIZE; - } - if (_emm_data.non_current->knas_enc.value != NULL) { - rc = _security_knas_enc(&_emm_data.non_current->kasme, - &_emm_data.non_current->knas_enc, seea); - } - /* Derive the NAS integrity key */ - if (_emm_data.non_current->knas_int.value == NULL) { - _emm_data.non_current->knas_int.value = - (uint8_t*)malloc(AUTH_KNAS_INT_SIZE); - _emm_data.non_current->knas_int.length = AUTH_KNAS_INT_SIZE; - } - if (_emm_data.non_current->knas_int.value != NULL) { - if (rc != RETURNerror) { - rc = _security_knas_int(&_emm_data.non_current->kasme, - &_emm_data.non_current->knas_int, seea); - } - } - /* Derive the eNodeB key */ - if (_security_data.kenb.value == NULL) { - _security_data.kenb.value = (uint8_t*)malloc(AUTH_KENB_SIZE); - _security_data.kenb.length = AUTH_KENB_SIZE; - } - if (_security_data.kenb.value != NULL) { - if (rc != RETURNerror) { - rc = _security_kenb(&_security_data.kenb, - &_emm_data.security->kasme, - *(UInt32_t*)(&_emm_data.non_current->ul_count)); - } - } - - /* - * NAS security mode command accepted by the UE - */ - if (rc != RETURNerror) { - /* Update the current EPS security context */ - if ( native_ksi && (_emm_data.security->type != EMM_KSI_NATIVE) ) { - /* The type of security context flag included in the SECURITY - * MODE COMMAND message is set to "native security context" and - * the UE has a mapped EPS security context as the current EPS - * security context */ - if ( (_emm_data.non_current->type == EMM_KSI_NATIVE) && - (_emm_data.non_current->eksi == ksi) ) { - /* The KSI matches the non-current native EPS security - * context; the UE shall take the non-current native EPS - * security context into use which then becomes the - * current native EPS security context and delete the - * mapped EPS security context */ - LOG_TRACE(INFO, - "EMM-PROC - Update Current security context"); - /* Release non-current security context */ - _security_release(_emm_data.security); - _emm_data.security = _emm_data.non_current; - /* Reset the uplink NAS COUNT counter */ - _emm_data.security->ul_count.overflow = 0; - _emm_data.security->ul_count.seq_num = 0; - /* Set new security context indicator */ - security_context_is_new = TRUE; - } - } - - if ( !native_ksi && (_emm_data.security->type != EMM_KSI_NATIVE) ) { - /* The type of security context flag included in the SECURITY - * MODE COMMAND message is set to "mapped security context" and - * the UE has a mapped EPS security context as the current EPS - * security context */ - if (ksi != _emm_data.security->eksi) { - /* The KSI does not match the current EPS security context; - * the UE shall reset the uplink NAS COUNT counter */ - LOG_TRACE(INFO, - "EMM-PROC - Reset uplink NAS COUNT counter"); - _emm_data.security->ul_count.overflow = 0; - _emm_data.security->ul_count.seq_num = 0; - } - } - } - /* - * NAS security mode command not accepted by the UE - */ - else { - /* Setup EMM cause code */ - emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED; - /* Release security mode control internal data */ - if (_security_data.kenb.value) { - free(_security_data.kenb.value); - _security_data.kenb.value = NULL; - _security_data.kenb.length = 0; - } - } + /* Update selected cyphering and integrity algorithms */ + _emm_data.non_current->capability.encryption = seea; + _emm_data.non_current->capability.integrity = seia; + + /* Derive the NAS cyphering key */ + if (_emm_data.non_current->knas_enc.value == NULL) { + _emm_data.non_current->knas_enc.value = + (uint8_t *)malloc(AUTH_KNAS_ENC_SIZE); + _emm_data.non_current->knas_enc.length = AUTH_KNAS_ENC_SIZE; + } + if (_emm_data.non_current->knas_enc.value != NULL) { + rc = _security_knas_enc(&_emm_data.non_current->kasme, + &_emm_data.non_current->knas_enc, seea); + } + /* Derive the NAS integrity key */ + if (_emm_data.non_current->knas_int.value == NULL) { + _emm_data.non_current->knas_int.value = + (uint8_t *)malloc(AUTH_KNAS_INT_SIZE); + _emm_data.non_current->knas_int.length = AUTH_KNAS_INT_SIZE; + } + if (_emm_data.non_current->knas_int.value != NULL) { + if (rc != RETURNerror) { + rc = _security_knas_int(&_emm_data.non_current->kasme, + &_emm_data.non_current->knas_int, seea); + } + } + /* Derive the eNodeB key */ + if (_security_data.kenb.value == NULL) { + _security_data.kenb.value = (uint8_t *)malloc(AUTH_KENB_SIZE); + _security_data.kenb.length = AUTH_KENB_SIZE; + } + if (_security_data.kenb.value != NULL) { + if (rc != RETURNerror) { + rc = _security_kenb(&_security_data.kenb, + &_emm_data.security->kasme, + *(UInt32_t *)(&_emm_data.non_current->ul_count)); + } + } + + /* + * NAS security mode command accepted by the UE + */ + if (rc != RETURNerror) { + /* Update the current EPS security context */ + if ( native_ksi && (_emm_data.security->type != EMM_KSI_NATIVE) ) { + /* The type of security context flag included in the SECURITY + * MODE COMMAND message is set to "native security context" and + * the UE has a mapped EPS security context as the current EPS + * security context */ + if ( (_emm_data.non_current->type == EMM_KSI_NATIVE) && + (_emm_data.non_current->eksi == ksi) ) { + /* The KSI matches the non-current native EPS security + * context; the UE shall take the non-current native EPS + * security context into use which then becomes the + * current native EPS security context and delete the + * mapped EPS security context */ + LOG_TRACE(INFO, + "EMM-PROC - Update Current security context"); + /* Release non-current security context */ + _security_release(_emm_data.security); + _emm_data.security = _emm_data.non_current; + /* Reset the uplink NAS COUNT counter */ + _emm_data.security->ul_count.overflow = 0; + _emm_data.security->ul_count.seq_num = 0; + /* Set new security context indicator */ + security_context_is_new = TRUE; + } + } + + if ( !native_ksi && (_emm_data.security->type != EMM_KSI_NATIVE) ) { + /* The type of security context flag included in the SECURITY + * MODE COMMAND message is set to "mapped security context" and + * the UE has a mapped EPS security context as the current EPS + * security context */ + if (ksi != _emm_data.security->eksi) { + /* The KSI does not match the current EPS security context; + * the UE shall reset the uplink NAS COUNT counter */ + LOG_TRACE(INFO, + "EMM-PROC - Reset uplink NAS COUNT counter"); + _emm_data.security->ul_count.overflow = 0; + _emm_data.security->ul_count.seq_num = 0; + } + } + } + /* + * NAS security mode command not accepted by the UE + */ + else { + /* Setup EMM cause code */ + emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED; + /* Release security mode control internal data */ + if (_security_data.kenb.value) { + free(_security_data.kenb.value); + _security_data.kenb.value = NULL; + _security_data.kenb.length = 0; + } + } } /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ rc = emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); if (rc != RETURNok) { - LOG_TRACE(WARNING, - "EMM-PROC - Failed to initialize EMM procedure handler"); - LOG_FUNC_RETURN (RETURNerror); + LOG_TRACE(WARNING, + "EMM-PROC - Failed to initialize EMM procedure handler"); + LOG_FUNC_RETURN (RETURNerror); } /* @@ -309,7 +312,7 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, emm_sap.u.emm_as.u.security.emm_cause = emm_cause; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, security_context_is_new, TRUE); + _emm_data.security, security_context_is_new, TRUE); rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN (rc); @@ -318,47 +321,47 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, /* * -------------------------------------------------------------------------- - * Security mode control procedure executed by the MME + * Security mode control procedure executed by the MME * -------------------------------------------------------------------------- */ #ifdef NAS_MME /**************************************************************************** ** ** - ** Name: emm_proc_security_mode_control() ** + ** Name: emm_proc_security_mode_control() ** ** ** ** Description: Initiates the security mode control procedure. ** ** ** ** 3GPP TS 24.301, section 5.4.3.2 ** - ** The MME initiates the NAS security mode control procedure ** - ** by sending a SECURITY MODE COMMAND message to the UE and ** - ** starting timer T3460. The message shall be sent unciphe- ** - ** red but shall be integrity protected using the NAS inte- ** - ** grity key based on KASME. ** - ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** ksi: NAS key set identifier ** - ** eea: Replayed EPS encryption algorithms ** - ** eia: Replayed EPS integrity algorithms ** - ** success: Callback function executed when the secu- ** - ** rity mode control procedure successfully ** - ** completes ** - ** reject: Callback function executed when the secu- ** - ** rity mode control procedure fails or is ** - ** rejected ** - ** failure: Callback function executed whener a lower ** - ** layer failure occured before the security ** - ** mode control procedure comnpletes ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** The MME initiates the NAS security mode control procedure ** + ** by sending a SECURITY MODE COMMAND message to the UE and ** + ** starting timer T3460. The message shall be sent unciphe- ** + ** red but shall be integrity protected using the NAS inte- ** + ** grity key based on KASME. ** + ** ** + ** Inputs: ueid: UE lower layer identifier ** + ** ksi: NAS key set identifier ** + ** eea: Replayed EPS encryption algorithms ** + ** eia: Replayed EPS integrity algorithms ** + ** success: Callback function executed when the secu- ** + ** rity mode control procedure successfully ** + ** completes ** + ** reject: Callback function executed when the secu- ** + ** rity mode control procedure fails or is ** + ** rejected ** + ** failure: Callback function executed whener a lower ** + ** layer failure occured before the security ** + ** mode control procedure comnpletes ** + ** Others: None ** + ** ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia, - emm_common_success_callback_t success, - emm_common_reject_callback_t reject, - emm_common_failure_callback_t failure) + emm_common_success_callback_t success, + emm_common_reject_callback_t reject, + emm_common_failure_callback_t failure) { LOG_FUNC_IN; @@ -366,10 +369,10 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia, int security_context_is_new = FALSE; LOG_TRACE(INFO, "EMM-PROC - Initiate security mode control procedure " - "KSI = %d", ksi); + "KSI = %d", ksi); /* Get the UE context */ - emm_data_context_t* emm_ctx = NULL; + emm_data_context_t *emm_ctx = NULL; #if defined(EPC_BUILD) if (ueid > 0) { @@ -382,62 +385,61 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia, #endif if (emm_ctx && emm_ctx->security) { - if (emm_ctx->security->type == EMM_KSI_NOT_AVAILABLE) { - /* The security mode control procedure is initiated to take into use - * the EPS security context created after a successful execution of - * the EPS authentication procedure */ - emm_ctx->security->type = EMM_KSI_NATIVE; - emm_ctx->security->eksi = ksi; - emm_ctx->security->dl_count.overflow = 0; - emm_ctx->security->dl_count.seq_num = 0; - - /* TODO !!! Compute Kasme, and NAS cyphering and integrity keys */ - - /* Set new security context indicator */ - security_context_is_new = TRUE; - } - } - else { - LOG_TRACE(WARNING, "EMM-PROC - No EPS security context exists"); - LOG_FUNC_RETURN (RETURNerror); + if (emm_ctx->security->type == EMM_KSI_NOT_AVAILABLE) { + /* The security mode control procedure is initiated to take into use + * the EPS security context created after a successful execution of + * the EPS authentication procedure */ + emm_ctx->security->type = EMM_KSI_NATIVE; + emm_ctx->security->eksi = ksi; + emm_ctx->security->dl_count.overflow = 0; + emm_ctx->security->dl_count.seq_num = 0; + + /* TODO !!! Compute Kasme, and NAS cyphering and integrity keys */ + + /* Set new security context indicator */ + security_context_is_new = TRUE; + } + } else { + LOG_TRACE(WARNING, "EMM-PROC - No EPS security context exists"); + LOG_FUNC_RETURN (RETURNerror); } /* Allocate parameters of the retransmission timer callback */ - security_data_t* data = - (security_data_t*)malloc(sizeof(security_data_t)); + security_data_t *data = + (security_data_t *)malloc(sizeof(security_data_t)); if (data != NULL) { - /* Setup ongoing EMM procedure callback functions */ - rc = emm_proc_common_initialize(ueid, success, reject, failure, - _security_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 key set identifier */ - data->ksi = ksi; - /* Set the EPS encryption algorithms to be replayed to the UE */ - data->eea = eea; - /* Set the EPS integrity algorithms to be replayed to the UE */ - data->eia = eia; - /* Set the failure notification indicator */ - data->notify_failure = FALSE; - /* Send security mode command message to the UE */ - rc = _security_request(data, security_context_is_new); - if (rc != RETURNerror) { - /* - * Notify EMM that common procedure has been initiated - */ - emm_sap_t emm_sap; - emm_sap.primitive = EMMREG_COMMON_PROC_REQ; - emm_sap.u.emm_reg.ueid = ueid; - rc = emm_sap_send(&emm_sap); - } + /* Setup ongoing EMM procedure callback functions */ + rc = emm_proc_common_initialize(ueid, success, reject, failure, + _security_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 key set identifier */ + data->ksi = ksi; + /* Set the EPS encryption algorithms to be replayed to the UE */ + data->eea = eea; + /* Set the EPS integrity algorithms to be replayed to the UE */ + data->eia = eia; + /* Set the failure notification indicator */ + data->notify_failure = FALSE; + /* Send security mode command message to the UE */ + rc = _security_request(data, security_context_is_new); + if (rc != RETURNerror) { + /* + * Notify EMM that common procedure has been initiated + */ + emm_sap_t emm_sap; + emm_sap.primitive = EMMREG_COMMON_PROC_REQ; + emm_sap.u.emm_reg.ueid = ueid; + rc = emm_sap_send(&emm_sap); + } } LOG_FUNC_RETURN (rc); @@ -445,29 +447,29 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia, /**************************************************************************** ** ** - ** Name: emm_proc_security_mode_complete() ** + ** Name: emm_proc_security_mode_complete() ** ** ** ** Description: Performs the security mode control completion procedure ** - ** executed by the network. ** + ** executed by the network. ** ** ** ** 3GPP TS 24.301, section 5.4.3.4 ** - ** Upon receiving the SECURITY MODE COMPLETE message, the ** - ** MME shall stop timer T3460. ** - ** From this time onward the MME shall integrity protect and ** - ** encipher all signalling messages with the selected NAS ** - ** integrity and ciphering algorithms. ** + ** Upon receiving the SECURITY MODE COMPLETE message, the ** + ** MME shall stop timer T3460. ** + ** From this time onward the MME shall integrity protect and ** + ** encipher all signalling messages with the selected NAS ** + ** integrity and ciphering algorithms. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_security_mode_complete(unsigned int ueid) { - emm_data_context_t* emm_ctx = NULL; + emm_data_context_t *emm_ctx = NULL; int rc = RETURNerror; emm_sap_t emm_sap; @@ -481,8 +483,10 @@ int emm_proc_security_mode_complete(unsigned int ueid) T3460.id = nas_timer_stop(T3460.id); /* Release retransmission timer paramaters */ - security_data_t* data = (security_data_t*)(emm_proc_common_get_args(ueid)); - if (data) free(data); + security_data_t *data = (security_data_t *)(emm_proc_common_get_args(ueid)); + if (data) { + free(data); + } /* Get the UE context */ #if defined(EPC_BUILD) @@ -496,20 +500,19 @@ int emm_proc_security_mode_complete(unsigned int ueid) #endif if (emm_ctx && emm_ctx->security) { - /* - * Notify EMM that the authentication procedure successfully completed - */ - emm_sap.primitive = EMMREG_COMMON_PROC_CNF; - emm_sap.u.emm_reg.ueid = ueid; - emm_sap.u.emm_reg.u.common.is_attached = emm_ctx->is_attached; - } - else { - LOG_TRACE(ERROR, "EMM-PROC - No EPS security context exists"); - /* - * Notify EMM that the authentication procedure failed - */ - emm_sap.primitive = EMMREG_COMMON_PROC_REJ; - emm_sap.u.emm_reg.ueid = ueid; + /* + * Notify EMM that the authentication procedure successfully completed + */ + emm_sap.primitive = EMMREG_COMMON_PROC_CNF; + emm_sap.u.emm_reg.ueid = ueid; + emm_sap.u.emm_reg.u.common.is_attached = emm_ctx->is_attached; + } else { + LOG_TRACE(ERROR, "EMM-PROC - No EPS security context exists"); + /* + * Notify EMM that the authentication procedure failed + */ + emm_sap.primitive = EMMREG_COMMON_PROC_REJ; + emm_sap.u.emm_reg.ueid = ueid; } rc = emm_sap_send(&emm_sap); @@ -519,31 +522,31 @@ int emm_proc_security_mode_complete(unsigned int ueid) /**************************************************************************** ** ** - ** Name: emm_proc_security_mode_reject() ** + ** Name: emm_proc_security_mode_reject() ** ** ** ** Description: Performs the security mode control not accepted by the UE ** ** ** ** 3GPP TS 24.301, section 5.4.3.5 ** - ** Upon receiving the SECURITY MODE REJECT message, the MME ** - ** shall stop timer T3460 and abort the ongoing procedure ** - ** that triggered the initiation of the NAS security mode ** - ** control procedure. ** - ** The MME shall apply the EPS security context in use befo- ** - ** re the initiation of the security mode control procedure, ** - ** if any, to protect any subsequent messages. ** + ** Upon receiving the SECURITY MODE REJECT message, the MME ** + ** shall stop timer T3460 and abort the ongoing procedure ** + ** that triggered the initiation of the NAS security mode ** + ** control procedure. ** + ** The MME shall apply the EPS security context in use befo- ** + ** re the initiation of the security mode control procedure, ** + ** if any, to protect any subsequent messages. ** ** ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ int emm_proc_security_mode_reject(unsigned int ueid) { - emm_data_context_t* emm_ctx = NULL; + emm_data_context_t *emm_ctx = NULL; int rc = RETURNerror; LOG_FUNC_IN; @@ -556,8 +559,10 @@ int emm_proc_security_mode_reject(unsigned int ueid) T3460.id = nas_timer_stop(T3460.id); /* Release retransmission timer paramaters */ - security_data_t* data = (security_data_t*)(emm_proc_common_get_args(ueid)); - if (data) free(data); + security_data_t *data = (security_data_t *)(emm_proc_common_get_args(ueid)); + if (data) { + free(data); + } /* Get the UE context */ #if defined(EPC_BUILD) @@ -571,13 +576,13 @@ int emm_proc_security_mode_reject(unsigned int ueid) #endif /* Set the key set identifier to its previous value */ if (emm_ctx && emm_ctx->security) { - /* XXX - Usually, the MME should be able to maintain a current and - * a non-current EPS security context simultaneously as the UE do. - * This implementation choose to have only one security context by UE - * in the MME, thus security mode control procedure is only performed - * to take into use the first EPS security context created after a - * successful execution of the EPS authentication procedure */ - emm_ctx->security->type = EMM_KSI_NOT_AVAILABLE; + /* XXX - Usually, the MME should be able to maintain a current and + * a non-current EPS security context simultaneously as the UE do. + * This implementation choose to have only one security context by UE + * in the MME, thus security mode control procedure is only performed + * to take into use the first EPS security context created after a + * successful execution of the EPS authentication procedure */ + emm_ctx->security->type = EMM_KSI_NOT_AVAILABLE; } /* @@ -599,37 +604,43 @@ int emm_proc_security_mode_reject(unsigned int ueid) #ifdef NAS_UE /* * -------------------------------------------------------------------------- - * UE specific local functions + * UE specific local functions * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _security_release() ** + ** Name: _security_release() ** ** ** ** Description: Releases the given EPS NAS security context ** ** ** - ** Inputs: ctx: The EPS NAS security context to release ** - ** Others: None ** + ** Inputs: ctx: The EPS NAS security context to release ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ -static void _security_release(emm_security_context_t* ctx) +static void _security_release(emm_security_context_t *ctx) { LOG_FUNC_IN; if (ctx) { - /* Release Kasme security key */ - if (ctx->kasme.value) free(ctx->kasme.value); - /* Release NAS cyphering key */ - if (ctx->knas_enc.value) free(ctx->knas_enc.value); - /* Release NAS integrity key */ - if (ctx->knas_int.value) free(ctx->knas_int.value); - /* Release the NAS security context */ - free(ctx); + /* Release Kasme security key */ + if (ctx->kasme.value) { + free(ctx->kasme.value); + } + /* Release NAS cyphering key */ + if (ctx->knas_enc.value) { + free(ctx->knas_enc.value); + } + /* Release NAS integrity key */ + if (ctx->knas_int.value) { + free(ctx->knas_int.value); + } + /* Release the NAS security context */ + free(ctx); } LOG_FUNC_OUT; @@ -637,24 +648,24 @@ static void _security_release(emm_security_context_t* ctx) /**************************************************************************** ** ** - ** Name: _security_knas_enc() ** + ** Name: _security_knas_enc() ** ** ** ** Description: Algorithm Key generation function used for the derivation ** - ** of NAS encryption key Knas-enc from the Kasme. ** + ** of NAS encryption key Knas-enc from the Kasme. ** ** ** ** 3GPP TS 33.401, Annex A.7 ** ** ** - ** Inputs: kasme: Key Access Security Management Entity ** - ** eea: Cyphering algorithm identity ** - ** Others: None ** + ** Inputs: kasme: Key Access Security Management Entity ** + ** eea: Cyphering algorithm identity ** + ** Others: None ** ** ** - ** Outputs: knas_enc: Derived key for NAS cyphering algorithm ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: knas_enc: Derived key for NAS cyphering algorithm ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -static int _security_knas_enc(const OctetString* kasme, OctetString* knas_enc, - UInt8_t eea) +static int _security_knas_enc(const OctetString *kasme, OctetString *knas_enc, + UInt8_t eea) { LOG_FUNC_IN; LOG_FUNC_RETURN (_security_kdf(kasme, knas_enc, 0x01, eea)); @@ -662,24 +673,24 @@ static int _security_knas_enc(const OctetString* kasme, OctetString* knas_enc, /**************************************************************************** ** ** - ** Name: _security_knas_int() ** + ** Name: _security_knas_int() ** ** ** ** Description: Algorithm Key generation function used for the derivation ** - ** of NAS integrity key Knas-int from the Kasme. ** + ** of NAS integrity key Knas-int from the Kasme. ** ** ** ** 3GPP TS 33.401, Annex A.7 ** ** ** - ** Inputs: kasme: Key Access Security Management Entity ** - ** eia: Integrity algorithm identity ** - ** Others: None ** + ** Inputs: kasme: Key Access Security Management Entity ** + ** eia: Integrity algorithm identity ** + ** Others: None ** ** ** - ** Outputs: knas_int: Derived key for NAS integrity algorithm ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: knas_int: Derived key for NAS integrity algorithm ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -static int _security_knas_int(const OctetString* kasme, OctetString* knas_int, - UInt8_t eia) +static int _security_knas_int(const OctetString *kasme, OctetString *knas_int, + UInt8_t eia) { LOG_FUNC_IN; LOG_FUNC_RETURN (_security_kdf(kasme, knas_int, 0x02, eia)); @@ -687,24 +698,24 @@ static int _security_knas_int(const OctetString* kasme, OctetString* knas_int, /**************************************************************************** ** ** - ** Name: _security_kenb() ** + ** Name: _security_kenb() ** ** ** ** Description: Computes the eNodeB key from Kasme and the given value of ** - ** uplink NAS counter. ** + ** uplink NAS counter. ** ** ** ** 3GPP TS 33.401, Annex A.3 ** ** ** - ** Inputs: kasme: Key Access Security Management Entity ** - ** count: Uplink NAS counter value ** - ** Others: None ** + ** Inputs: kasme: Key Access Security Management Entity ** + ** count: Uplink NAS counter value ** + ** Others: None ** ** ** - ** Outputs: kenb: eNodeB security key ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: kenb: eNodeB security key ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -static int _security_kenb(const OctetString* kasme, OctetString* kenb, - UInt32_t count) +static int _security_kenb(const OctetString *kasme, OctetString *kenb, + UInt32_t count) { /* Compute the KDF input parameter * S = FC(0x11) || UL NAS Count || 0x00 0x04 @@ -713,8 +724,10 @@ static int _security_kenb(const OctetString* kasme, OctetString* kenb, UInt16_t length = 4; int offset = 0; - input[offset] = 0x11; offset += 1; - input[offset] = count; offset += length; + input[offset] = 0x11; + offset += 1; + input[offset] = count; + offset += length; input[offset] = length; /* TODO !!! Compute the derived key */ @@ -724,40 +737,44 @@ static int _security_kenb(const OctetString* kasme, OctetString* kenb, /**************************************************************************** ** ** - ** Name: _security_kdf() ** + ** Name: _security_kdf() ** ** ** ** Description: Algorithm Key generation function used for the derivation ** - ** of keys for NAS integrity and NAS encryption algorithms ** - ** from Kasme, algorithm types and algorithm identities. ** + ** of keys for NAS integrity and NAS encryption algorithms ** + ** from Kasme, algorithm types and algorithm identities. ** ** ** ** 3GPP TS 33.401, Annex A.7 ** ** ** - ** Inputs: kasme: Key Access Security Management Entity ** - ** algo_dist: Algorithm type distinguisher ** - ** algo_id: Algorithm identity ** - ** Others: None ** + ** Inputs: kasme: Key Access Security Management Entity ** + ** algo_dist: Algorithm type distinguisher ** + ** algo_id: Algorithm identity ** + ** Others: None ** ** ** - ** Outputs: key: Derived key for NAS security protection ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: key: Derived key for NAS security protection ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ -static int _security_kdf(const OctetString* kasme, OctetString* key, - UInt8_t algo_dist, UInt8_t algo_id) +static int _security_kdf(const OctetString *kasme, OctetString *key, + UInt8_t algo_dist, UInt8_t algo_id) { /* Compute the KDF input parameter * S = FC(0x15) || Algorithm distinguisher || 0x00 0x01 - || Algorithm identity || 0x00 0x01 + || Algorithm identity || 0x00 0x01 */ UInt8_t input[kasme->length]; UInt16_t length = 1; int offset = 0; int size_of_length = sizeof(length); - input[offset] = 0x15; offset += 1; - input[offset] = algo_dist; offset += length; - input[offset] = length; offset += size_of_length; - input[offset] = algo_id; offset += length; + input[offset] = 0x15; + offset += 1; + input[offset] = algo_dist; + offset += length; + input[offset] = length; + offset += size_of_length; + input[offset] = algo_id; + offset += length; input[offset] = length; /* TODO !!! Compute the derived key */ @@ -769,53 +786,52 @@ static int _security_kdf(const OctetString* kasme, OctetString* key, #ifdef NAS_MME /* * -------------------------------------------------------------------------- - * Timer handlers + * Timer handlers * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _security_t3460_handler() ** + ** Name: _security_t3460_handler() ** ** ** ** Description: T3460 timeout handler ** - ** Upon T3460 timer expiration, the security mode command ** - ** message is retransmitted and the timer restarted. When ** - ** retransmission counter is exceed, the MME shall abort the ** - ** security mode control procedure. ** + ** Upon T3460 timer expiration, the security mode command ** + ** message is retransmitted and the timer restarted. When ** + ** retransmission counter is exceed, the MME shall abort the ** + ** security mode control procedure. ** ** ** ** 3GPP TS 24.301, section 5.4.3.7, case b ** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ -static void* _security_t3460_handler(void* args) +static void *_security_t3460_handler(void *args) { LOG_FUNC_IN; int rc; - security_data_t* data = (security_data_t*)(args); + security_data_t *data = (security_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); + "counter = %d", data->retransmission_count); if (data->retransmission_count < SECURITY_COUNTER_MAX) { - /* Send security mode command message to the UE */ - rc = _security_request(data, FALSE); - } - else { - /* Set the failure notification indicator */ - data->notify_failure = TRUE; - /* Abort the security mode control procedure */ - rc = _security_abort(data); + /* Send security mode command message to the UE */ + rc = _security_request(data, FALSE); + } else { + /* Set the failure notification indicator */ + data->notify_failure = TRUE; + /* Abort the security mode control procedure */ + rc = _security_abort(data); } LOG_FUNC_RETURN (NULL); @@ -823,27 +839,27 @@ static void* _security_t3460_handler(void* args) /* * -------------------------------------------------------------------------- - * MME specific local functions + * MME specific local functions * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _security_request() ** + ** Name: _security_request() ** ** ** ** Description: Sends SECURITY MODE COMMAND message and start timer T3460 ** ** ** - ** Inputs: data: Security mode control internal data ** - ** is_new: Indicates whether a new security context ** - ** has just been taken into use ** - ** Others: None ** + ** Inputs: data: Security mode control internal data ** + ** is_new: Indicates whether a new security context ** + ** has just been taken into use ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3460 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3460 ** ** ** ***************************************************************************/ -int _security_request(security_data_t* data, int is_new) +int _security_request(security_data_t *data, int is_new) { struct emm_data_context_s *emm_ctx = NULL; @@ -880,15 +896,15 @@ int _security_request(security_data_t* data, int is_new) rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { - if (T3460.id != NAS_TIMER_INACTIVE_ID) { - /* Re-start T3460 timer */ - T3460.id = nas_timer_restart(T3460.id); - } else { - /* Start T3460 timer */ - T3460.id = nas_timer_start(T3460.sec, _security_t3460_handler, data); - } - LOG_TRACE(INFO,"EMM-PROC - Timer T3460 (%d) expires in %ld seconds", - T3460.id, T3460.sec); + if (T3460.id != NAS_TIMER_INACTIVE_ID) { + /* Re-start T3460 timer */ + T3460.id = nas_timer_restart(T3460.id); + } else { + /* Start T3460 timer */ + T3460.id = nas_timer_start(T3460.sec, _security_t3460_handler, data); + } + LOG_TRACE(INFO,"EMM-PROC - Timer T3460 (%d) expires in %ld seconds", + T3460.id, T3460.sec); } LOG_FUNC_RETURN (rc); @@ -896,54 +912,53 @@ int _security_request(security_data_t* data, int is_new) /**************************************************************************** ** ** - ** Name: _security_abort() ** + ** Name: _security_abort() ** ** ** ** Description: Aborts the security mode control procedure currently in ** - ** progress ** + ** progress ** ** ** - ** Inputs: args: Security mode control data to be released ** - ** Others: None ** + ** Inputs: args: Security mode control data to be released ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: T3460 ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: T3460 ** ** ** ***************************************************************************/ -static int _security_abort(void* args) +static int _security_abort(void *args) { LOG_FUNC_IN; int rc = RETURNerror; - security_data_t* data = (security_data_t*)(args); - - if (data) - { - unsigned int ueid = data->ueid; - int notify_failure = data->notify_failure; - - LOG_TRACE(WARNING, "EMM-PROC - Abort security mode control procedure " - "(ueid=%u)", ueid); - - /* Stop timer T3460 */ - if (T3460.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3460 (%d)", T3460.id); - T3460.id = nas_timer_stop(T3460.id); - } - /* Release retransmission timer paramaters */ - free(data); - - /* - * Notify EMM that the security mode control 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; - } + security_data_t *data = (security_data_t *)(args); + + if (data) { + unsigned int ueid = data->ueid; + int notify_failure = data->notify_failure; + + LOG_TRACE(WARNING, "EMM-PROC - Abort security mode control procedure " + "(ueid=%u)", ueid); + + /* Stop timer T3460 */ + if (T3460.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3460 (%d)", T3460.id); + T3460.id = nas_timer_stop(T3460.id); + } + /* Release retransmission timer paramaters */ + free(data); + + /* + * Notify EMM that the security mode control 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); diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/ServiceRequestHdl.c b/openair-cn/NAS/EURECOM-NAS/src/emm/ServiceRequestHdl.c index b7fbcd898a3ea50564364e8d2ef241880da26d16..7d6dc2d7425cc52e756eba60d356566fd60456b3 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/ServiceRequestHdl.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/ServiceRequestHdl.c @@ -1,30 +1,30 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source ServiceRequest.c +Source ServiceRequest.c -Version 0.1 +Version 0.1 -Date 2013/05/07 +Date 2013/05/07 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines the service request EMM procedure executed by the - Non-Access Stratum. +Description Defines the service request EMM procedure executed by the + Non-Access Stratum. - The purpose of the service request procedure is to transfer - the EMM mode from EMM-IDLE to EMM-CONNECTED mode and establish - the radio and S1 bearers when uplink user data or signalling - is to be sent. + The purpose of the service request procedure is to transfer + the EMM mode from EMM-IDLE to EMM-CONNECTED mode and establish + the radio and S1 bearers when uplink user data or signalling + is to be sent. - This procedure is used when the network has downlink signalling - pending, the UE has uplink signalling pending, the UE or the - network has user data pending and the UE is in EMM-IDLE mode. + This procedure is used when the network has downlink signalling + pending, the UE has uplink signalling pending, the UE or the + network has user data pending and the UE is in EMM-IDLE mode. *****************************************************************************/ @@ -46,19 +46,19 @@ Description Defines the service request EMM procedure executed by the /* * -------------------------------------------------------------------------- - * Internal data handled by the service request procedure in the UE + * Internal data handled by the service request procedure in the UE * -------------------------------------------------------------------------- */ #ifdef NAS_UE /* * Timer handlers */ -void* _emm_service_t3417_handler(void*); +void *_emm_service_t3417_handler(void *); #endif // NAS_UE /* * -------------------------------------------------------------------------- - * Internal data handled by the service request procedure in the MME + * Internal data handled by the service request procedure in the MME * -------------------------------------------------------------------------- */ #ifdef NAS_MME @@ -75,27 +75,27 @@ void* _emm_service_t3417_handler(void*); #ifdef NAS_UE /* * -------------------------------------------------------------------------- - * Timer handlers + * Timer handlers * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _emm_service_t3417_handler() ** + ** Name: _emm_service_t3417_handler() ** ** ** ** Description: T3417 timeout handler ** ** ** ** 3GPP TS 24.301, section 5.6.1.6 case c ** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ -void* _emm_service_t3417_handler(void* args) +void *_emm_service_t3417_handler(void *args) { LOG_FUNC_IN; diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/TrackingAreaUpdate.c b/openair-cn/NAS/EURECOM-NAS/src/emm/TrackingAreaUpdate.c index 05d4592e75d656b0a7979c6abccc0eda9abf0378..4ff7e485f75f50ed11fc4afe8c842eaed659f678 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/TrackingAreaUpdate.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/TrackingAreaUpdate.c @@ -1,27 +1,27 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source TrackingAreaUpdate.c +Source TrackingAreaUpdate.c -Version 0.1 +Version 0.1 -Date 2013/05/07 +Date 2013/05/07 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines the tracking area update EMM procedure executed by the - Non-Access Stratum. +Description Defines the tracking area update EMM procedure executed by the + Non-Access Stratum. - The tracking area updating procedure is always initiated by the - UE and is used to update the registration of the actual tracking - area of a UE in the network, to periodically notify the availa- - bility of the UE to the network, for MME load balancing, to up- - date certain UE specific parameters in the network. + The tracking area updating procedure is always initiated by the + UE and is used to update the registration of the actual tracking + area of a UE in the network, to periodically notify the availa- + bility of the UE to the network, for MME load balancing, to up- + date certain UE specific parameters in the network. *****************************************************************************/ @@ -50,7 +50,7 @@ Description Defines the tracking area update EMM procedure executed by the /* * Timer handlers */ -void* _emm_tau_t3430_handler(void*); +void *_emm_tau_t3430_handler(void *); #endif // NAS_UE /* @@ -72,27 +72,27 @@ void* _emm_tau_t3430_handler(void*); #ifdef NAS_UE /* * -------------------------------------------------------------------------- - * Timer handlers + * Timer handlers * -------------------------------------------------------------------------- */ /**************************************************************************** ** ** - ** Name: _emm_tau_t3430_handler() ** + ** Name: _emm_tau_t3430_handler() ** ** ** ** Description: T3430 timeout handler ** ** ** ** 3GPP TS 24.301, section 5.5.3.2.6 case c ** ** ** - ** Inputs: args: handler parameters ** - ** Others: None ** + ** Inputs: args: handler parameters ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ -void* _emm_tau_t3430_handler(void* args) +void *_emm_tau_t3430_handler(void *args) { LOG_FUNC_IN; diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h b/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h index d32d3557e53d4e7e8f871455a92e98f75ad5d023..d98656aaadb5847674cd1e20e45631e96741c3b9 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h @@ -1,21 +1,21 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source emmData.h +Source emmData.h -Version 0.1 +Version 0.1 -Date 2012/10/18 +Date 2012/10/18 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines internal private data handled by EPS Mobility - Management sublayer. +Description Defines internal private data handled by EPS Mobility + Management sublayer. *****************************************************************************/ #ifndef __EMMDATA_H__ @@ -45,37 +45,37 @@ Description Defines internal private data handled by EPS Mobility * The name of the file used as non-volatile memory device to store * persistent EMM data when the UE is switched off */ -#define EMM_NVRAM_FILENAME ".ue_emm.nvram" +#define EMM_NVRAM_FILENAME ".ue_emm.nvram" /* * The name of the environment variable which defines the directory * where the EMM data file is located */ -#define EMM_NVRAM_DIRNAME "NVRAM_DIR" +#define EMM_NVRAM_DIRNAME "NVRAM_DIR" /* Network selection modes of operation */ -#define EMM_DATA_PLMN_AUTO NET_PLMN_AUTO -#define EMM_DATA_PLMN_MANUAL NET_PLMN_MANUAL +#define EMM_DATA_PLMN_AUTO NET_PLMN_AUTO +#define EMM_DATA_PLMN_MANUAL NET_PLMN_MANUAL #endif // NAS_UE /* Checks Mobile Country Code equality */ -#define MCCS_ARE_EQUAL(n1, n2) (((n1).MCCdigit1 == (n2).MCCdigit1) && \ - ((n1).MCCdigit2 == (n2).MCCdigit2) && \ - ((n1).MCCdigit3 == (n2).MCCdigit3)) +#define MCCS_ARE_EQUAL(n1, n2) (((n1).MCCdigit1 == (n2).MCCdigit1) && \ + ((n1).MCCdigit2 == (n2).MCCdigit2) && \ + ((n1).MCCdigit3 == (n2).MCCdigit3)) /* Checks Mobile Network Code equality */ -#define MNCS_ARE_EQUAL(n1, n2) (((n1).MNCdigit1 == (n2).MNCdigit1) && \ - ((n1).MNCdigit2 == (n2).MNCdigit2) && \ - ((n1).MNCdigit3 == (n2).MNCdigit3)) +#define MNCS_ARE_EQUAL(n1, n2) (((n1).MNCdigit1 == (n2).MNCdigit1) && \ + ((n1).MNCdigit2 == (n2).MNCdigit2) && \ + ((n1).MNCdigit3 == (n2).MNCdigit3)) /* Checks PLMNs equality */ -#define PLMNS_ARE_EQUAL(p1, p2) ((MCCS_ARE_EQUAL((p1),(p2))) && \ - (MNCS_ARE_EQUAL((p1),(p2)))) +#define PLMNS_ARE_EQUAL(p1, p2) ((MCCS_ARE_EQUAL((p1),(p2))) && \ + (MNCS_ARE_EQUAL((p1),(p2)))) /* Checks TAIs equality */ -#define TAIS_ARE_EQUAL(t1, t2) ((PLMNS_ARE_EQUAL((t1).plmn,(t2).plmn)) && \ - ((t1).tac == (t2).tac)) +#define TAIS_ARE_EQUAL(t1, t2) ((PLMNS_ARE_EQUAL((t1).plmn,(t2).plmn)) && \ + ((t1).tac == (t2).tac)) /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ @@ -96,21 +96,21 @@ typedef enum { /* EPS NAS security context structure */ typedef struct { - emm_ksi_t type; /* Type of security context */ - int eksi; /* NAS key set identifier for E-UTRAN */ - OctetString kasme; /* ASME security key (native context) */ - //OctetString ksgsn; /* SGSN security key (mapped context) */ - OctetString knas_enc; /* NAS cyphering key */ - OctetString knas_int; /* NAS integrity key */ + emm_ksi_t type; /* Type of security context */ + int eksi; /* NAS key set identifier for E-UTRAN */ + OctetString kasme; /* ASME security key (native context) */ + //OctetString ksgsn; /* SGSN security key (mapped context) */ + OctetString knas_enc; /* NAS cyphering key */ + OctetString knas_int; /* NAS integrity key */ struct { - UInt32_t spare:8; - UInt32_t overflow:16; - UInt32_t seq_num:8; - } dl_count, ul_count; /* Downlink and uplink count parameters */ + UInt32_t spare:8; + UInt32_t overflow:16; + UInt32_t seq_num:8; + } dl_count, ul_count; /* Downlink and uplink count parameters */ struct { - UInt8_t encryption:4; /* algorithm used for ciphering */ - UInt8_t integrity:4; /* algorithm used for integrity protection */ - } capability; /* UE network capability */ + UInt8_t encryption:4; /* algorithm used for ciphering */ + UInt8_t integrity:4; /* algorithm used for integrity protection */ + } capability; /* UE network capability */ } emm_security_context_t; /* @@ -129,11 +129,11 @@ typedef struct { * * EU1: The last attach or tracking area updating attempt was successful. * EU2: The last attach, service request or tracking area updating attempt - * failed procedurally, i.e. no response or reject message was received - * from the MME. + * failed procedurally, i.e. no response or reject message was received + * from the MME. * EU3: The last attach, service request or tracking area updating attempt - * was correctly performed, but the answer from the MME was negative - * (because of roaming or subscription restrictions). + * was correctly performed, but the answer from the MME was negative + * (because of roaming or subscription restrictions). */ typedef enum { EU1_UPDATED, @@ -144,10 +144,10 @@ typedef enum { /* * EPS Connection Management states * -------------------------------- - * ECM-IDLE: No NAS signalling connection between UE and network exists. - * No UE context exists in the network. + * ECM-IDLE: No NAS signalling connection between UE and network exists. + * No UE context exists in the network. * ECM-CONNECTED: The signalling connection is established between the UE - * and the MME (RRC connection and S1_MME connection). + * and the MME (RRC connection and S1_MME connection). */ typedef enum { ECM_IDLE, @@ -171,9 +171,9 @@ typedef enum { */ typedef struct { imsi_t imsi; - plmn_t rplmn; /* The registered PLMN */ - /* List of equivalent PLMNs */ -#define EMM_DATA_EPLMN_MAX 16 + plmn_t rplmn; /* The registered PLMN */ + /* List of equivalent PLMNs */ +#define EMM_DATA_EPLMN_MAX 16 PLMN_LIST_T(EMM_DATA_EPLMN_MAX) eplmn; } emm_nvdata_t; @@ -182,17 +182,17 @@ typedef struct { * ------------------------- */ typedef struct { - int usim_is_valid; /* Indication of USIM data validity */ + int usim_is_valid; /* Indication of USIM data validity */ - imei_t *imei; /* IMEI read from the UE's non-volatile memory */ - const imsi_t *imsi; /* The valid IMSI read from the USIM */ - GUTI_t *guti; /* The valid GUTI read from the USIM */ - tai_t *tai; /* Last visited registered Tracking Area Id */ + imei_t *imei; /* IMEI read from the UE's non-volatile memory */ + const imsi_t *imsi; /* The valid IMSI read from the USIM */ + GUTI_t *guti; /* The valid GUTI read from the USIM */ + tai_t *tai; /* Last visited registered Tracking Area Id */ - emm_eps_update_t status; /* The current EPS update status */ - emm_ecm_state_t ecm_status; /* The EPS Connection Management status */ - int is_attached; /* Network attachment indicator */ - int is_emergency; /* Emergency bearer services indicator */ + emm_eps_update_t status; /* The current EPS update status */ + emm_ecm_state_t ecm_status; /* The EPS Connection Management status */ + int is_attached; /* Network attachment indicator */ + int is_emergency; /* Emergency bearer services indicator */ /* Tracking Areas list the UE is registered to * Contains the list of TAIs that identify the tracking areas that @@ -200,84 +200,84 @@ typedef struct { * procedure. The TAIs in a TAI list assigned by an MME to a UE * pertain to the same MME area. */ -#define EMM_DATA_TAI_MAX 16 +#define EMM_DATA_TAI_MAX 16 TAI_LIST_T(EMM_DATA_TAI_MAX) ltai; - int plmn_mode; /* Network selection operating mode */ - int plmn_index; /* Manually selected PLMN */ - int plmn_rat; /* Manually selected Radio Access Technology */ + int plmn_mode; /* Network selection operating mode */ + int plmn_index; /* Manually selected PLMN */ + int plmn_rat; /* Manually selected Radio Access Technology */ - plmn_t splmn; /* The currently selected PLMN */ - int is_rplmn; /* splmn is the registered PLMN */ - int is_eplmn; /* splmn is in the list of equivalent PLMNs */ - Stat_t stat; /* Current network registration status */ - tac_t tac; /* Tracking area code */ - ci_t ci; /* GERAN/UTRAN/E-UTRAN serving cell identifier */ - AcT_t rat; /* Radio Access Technology of the serving cell */ + plmn_t splmn; /* The currently selected PLMN */ + int is_rplmn; /* splmn is the registered PLMN */ + int is_eplmn; /* splmn is in the list of equivalent PLMNs */ + Stat_t stat; /* Current network registration status */ + tac_t tac; /* Tracking area code */ + ci_t ci; /* GERAN/UTRAN/E-UTRAN serving cell identifier */ + AcT_t rat; /* Radio Access Technology of the serving cell */ /* An octet string representation of operators present in the network */ struct { -#define EMM_DATA_BUFFER_SIZE 2048 - char buffer[EMM_DATA_BUFFER_SIZE+1]; +#define EMM_DATA_BUFFER_SIZE 2048 + char buffer[EMM_DATA_BUFFER_SIZE+1]; } plist; /* * Data used for PLMN selection procedure * -------------------------------------- */ - plmn_t hplmn; /* The Home PLMN derived from the IMSI */ - /* List of Forbidden PLMNs - * Contains the list of PLMN identities for which a Location - * Registration has been rejected with EMM cause code #11 (PLMN - * not allowed). A PLMN is removed from this list if, after a - * subsequent manual selection of that PLMN, there is a successful - * Location Request. */ -#define EMM_DATA_FPLMN_MAX 4 + plmn_t hplmn; /* The Home PLMN derived from the IMSI */ + /* List of Forbidden PLMNs + * Contains the list of PLMN identities for which a Location + * Registration has been rejected with EMM cause code #11 (PLMN + * not allowed). A PLMN is removed from this list if, after a + * subsequent manual selection of that PLMN, there is a successful + * Location Request. */ +#define EMM_DATA_FPLMN_MAX 4 PLMN_LIST_T(EMM_DATA_FPLMN_MAX) fplmn; - /* List of Forbidden PLMNs for GPRS service - * Contains the list of PLMN identities for which an Attach Request - * has been rejected with EMM cause code #14 (GPRS/EPS services not - * allowed in this PLMN). A PLMN is removed from this list if, after - * a subsequent manual selection of that PLMN, there is a successful - * GPRS attach or EPS attach. */ -#define EMM_DATA_FPLMN_GPRS_MAX 4 + /* List of Forbidden PLMNs for GPRS service + * Contains the list of PLMN identities for which an Attach Request + * has been rejected with EMM cause code #14 (GPRS/EPS services not + * allowed in this PLMN). A PLMN is removed from this list if, after + * a subsequent manual selection of that PLMN, there is a successful + * GPRS attach or EPS attach. */ +#define EMM_DATA_FPLMN_GPRS_MAX 4 PLMN_LIST_T(EMM_DATA_FPLMN_GPRS_MAX) fplmn_gprs; - /* List of Equivalent HPLMNs */ -#define EMM_DATA_EHPLMN_MAX 4 + /* List of Equivalent HPLMNs */ +#define EMM_DATA_EHPLMN_MAX 4 PLMN_LIST_T(EMM_DATA_EHPLMN_MAX) ehplmn; - /* List of user controlled PLMNs */ -#define EMM_DATA_PLMN_MAX 4 + /* List of user controlled PLMNs */ +#define EMM_DATA_PLMN_MAX 4 PLMN_LIST_T(EMM_DATA_PLMN_MAX) plmn; UInt16_t userAcT[EMM_DATA_PLMN_MAX]; - /* List of operator controlled PLMNs */ -#define EMM_DATA_OPLMN_MAX 4 + /* List of operator controlled PLMNs */ +#define EMM_DATA_OPLMN_MAX 4 PLMN_LIST_T(EMM_DATA_OPLMN_MAX) oplmn; UInt16_t operAcT[EMM_DATA_OPLMN_MAX]; - /* List of operator network name records */ -#define EMM_DATA_OPNN_MAX 16 + /* List of operator network name records */ +#define EMM_DATA_OPNN_MAX 16 UInt8_t n_opnns; struct { - const plmn_t *plmn; - const char *fullname; - const char *shortname; + const plmn_t *plmn; + const char *fullname; + const char *shortname; } opnn[EMM_DATA_OPNN_MAX]; /* * Data used for roaming service * ----------------------------- */ - /* List of Forbidden Tracking Areas - * Contains the list of TAIs for which an attach request has been - * rejected with EMM cause code #12 (tracking area not allowed). - */ -#define EMM_DATA_FTAI_MAX 40 + /* List of Forbidden Tracking Areas + * Contains the list of TAIs for which an attach request has been + * rejected with EMM cause code #12 (tracking area not allowed). + */ +#define EMM_DATA_FTAI_MAX 40 TAI_LIST_T(EMM_DATA_FTAI_MAX) ftai; - /* List of Forbidden Tracking Areas for roaming - * Contains the list of TAIs for which an attach request has been - * rejected with EMM cause code #13 (roaming not allowed in this - * tracking area). - */ -#define EMM_DATA_FTAI_ROAMING_MAX 40 + /* List of Forbidden Tracking Areas for roaming + * Contains the list of TAIs for which an attach request has been + * rejected with EMM cause code #13 (roaming not allowed in this + * tracking area). + */ +#define EMM_DATA_FTAI_ROAMING_MAX 40 TAI_LIST_T(EMM_DATA_FTAI_ROAMING_MAX) ftai_roaming; /* @@ -302,8 +302,8 @@ typedef struct { * EPS NAS security context * ------------------------ */ - emm_security_context_t* security; /* current security context */ - emm_security_context_t* non_current; /* non-current security context */ + emm_security_context_t *security; /* current security context */ + emm_security_context_t *non_current; /* non-current security context */ } emm_data_t; @@ -320,28 +320,28 @@ typedef struct { * --------------------------------------------------------------------------- */ typedef struct emm_data_context_s { - unsigned int ueid; /* UE identifier */ - int is_dynamic; /* Dynamically allocated context indicator */ - int is_attached; /* Attachment indicator */ - int is_emergency; /* Emergency bearer services indicator */ - - imsi_t* imsi; /* The IMSI provided by the UE or the MME */ - imei_t* imei; /* The IMEI provided by the UE */ - int guti_is_new; /* New GUTI indicator */ - GUTI_t* guti; /* The GUTI assigned to the UE */ - GUTI_t* old_guti; /* The old GUTI */ - int n_tacs; /* Number of concecutive tracking areas the UE is - * registered to */ - tac_t tac; /* Code of the first tracking area the UE is - * registered to */ - - int ksi; /* Security key set identifier provided by the UE */ - int eea; /* EPS encryption algorithms supported by the UE */ - int eia; /* EPS integrity algorithms supported by the UE */ - auth_vector_t vector; /* EPS authentication vector */ - emm_security_context_t* security; /* Current EPS NAS security context */ + unsigned int ueid; /* UE identifier */ + int is_dynamic; /* Dynamically allocated context indicator */ + int is_attached; /* Attachment indicator */ + int is_emergency; /* Emergency bearer services indicator */ + + imsi_t *imsi; /* The IMSI provided by the UE or the MME */ + imei_t *imei; /* The IMEI provided by the UE */ + int guti_is_new; /* New GUTI indicator */ + GUTI_t *guti; /* The GUTI assigned to the UE */ + GUTI_t *old_guti; /* The old GUTI */ + int n_tacs; /* Number of concecutive tracking areas the UE is + * registered to */ + tac_t tac; /* Code of the first tracking area the UE is + * registered to */ + + int ksi; /* Security key set identifier provided by the UE */ + int eea; /* EPS encryption algorithms supported by the UE */ + int eia; /* EPS integrity algorithms supported by the UE */ + auth_vector_t vector; /* EPS authentication vector */ + emm_security_context_t *security; /* Current EPS NAS security context */ OctetString esm_msg; /* ESM message contained within the initial request */ - int emm_cause; /* EMM failure cause code */ + int emm_cause; /* EMM failure cause code */ emm_fsm_state_t _emm_fsm_status; @@ -368,15 +368,15 @@ typedef struct { /* Use a tree for ue data context within MME */ RB_HEAD(emm_data_context_map, emm_data_context_s) ctx_map; # else -# define EMM_DATA_NB_UE_MAX (MME_API_NB_UE_MAX + 1) - emm_data_context_t* ctx [EMM_DATA_NB_UE_MAX]; +# define EMM_DATA_NB_UE_MAX (MME_API_NB_UE_MAX + 1) + emm_data_context_t *ctx [EMM_DATA_NB_UE_MAX]; # endif } emm_data_t; struct emm_data_context_s *emm_data_context_get( emm_data_t *_emm_data, unsigned int _ueid); -struct emm_data_context_s * emm_data_context_remove( +struct emm_data_context_s *emm_data_context_remove( emm_data_t *_emm_data, struct emm_data_context_s *elm); void emm_data_context_add(emm_data_t *emm_data, struct emm_data_context_s *elm); @@ -389,58 +389,58 @@ void emm_data_context_add(emm_data_t *emm_data, struct emm_data_context_s *elm); /* * -------------------------------------------------------------------------- - * EPS mobility management data (used within EMM only) + * EPS mobility management data (used within EMM only) * -------------------------------------------------------------------------- */ emm_data_t _emm_data; /* * -------------------------------------------------------------------------- - * EPS mobility management timers – UE side + * EPS mobility management timers – UE side * -------------------------------------------------------------------------- */ #ifdef NAS_UE -#define T3402_DEFAULT_VALUE 720 /* 12 minutes */ -#define T3410_DEFAULT_VALUE 15 /* 15 seconds */ -#define T3411_DEFAULT_VALUE 10 /* 10 seconds */ -#define T3412_DEFAULT_VALUE 3240 /* 54 minutes */ -#define T3416_DEFAULT_VALUE 30 /* 30 seconds */ -#define T3417_DEFAULT_VALUE 5 /* 5 seconds */ -#define T3417ext_DEFAULT_VALUE 10 /* 10 seconds */ -#define T3418_DEFAULT_VALUE 20 /* 20 seconds */ -#define T3420_DEFAULT_VALUE 15 /* 15 seconds */ -#define T3421_DEFAULT_VALUE 15 /* 15 seconds */ -#define T3423_DEFAULT_VALUE T3412_DEFAULT_VALUE -#define T3430_DEFAULT_VALUE 15 /* 15 seconds */ -#define T3440_DEFAULT_VALUE 10 /* 10 seconds */ - -struct nas_timer_t T3402; /* attach failure timer */ -struct nas_timer_t T3410; /* attach timer */ -struct nas_timer_t T3411; /* attach restart timer */ -struct nas_timer_t T3412; /* periodic tracking area update timer */ -struct nas_timer_t T3416; /* EPS authentication challenge timer */ -struct nas_timer_t T3417; /* Service request timer */ -struct nas_timer_t T3418; /* MAC authentication failure timer */ -struct nas_timer_t T3420; /* Synch authentication failure timer */ -struct nas_timer_t T3421; /* Detach timer */ -struct nas_timer_t T3430; /* tracking area update timer */ - -struct nas_timer_t T3423; /* E-UTRAN deactivate ISR timer */ +#define T3402_DEFAULT_VALUE 720 /* 12 minutes */ +#define T3410_DEFAULT_VALUE 15 /* 15 seconds */ +#define T3411_DEFAULT_VALUE 10 /* 10 seconds */ +#define T3412_DEFAULT_VALUE 3240 /* 54 minutes */ +#define T3416_DEFAULT_VALUE 30 /* 30 seconds */ +#define T3417_DEFAULT_VALUE 5 /* 5 seconds */ +#define T3417ext_DEFAULT_VALUE 10 /* 10 seconds */ +#define T3418_DEFAULT_VALUE 20 /* 20 seconds */ +#define T3420_DEFAULT_VALUE 15 /* 15 seconds */ +#define T3421_DEFAULT_VALUE 15 /* 15 seconds */ +#define T3423_DEFAULT_VALUE T3412_DEFAULT_VALUE +#define T3430_DEFAULT_VALUE 15 /* 15 seconds */ +#define T3440_DEFAULT_VALUE 10 /* 10 seconds */ + +struct nas_timer_t T3402; /* attach failure timer */ +struct nas_timer_t T3410; /* attach timer */ +struct nas_timer_t T3411; /* attach restart timer */ +struct nas_timer_t T3412; /* periodic tracking area update timer */ +struct nas_timer_t T3416; /* EPS authentication challenge timer */ +struct nas_timer_t T3417; /* Service request timer */ +struct nas_timer_t T3418; /* MAC authentication failure timer */ +struct nas_timer_t T3420; /* Synch authentication failure timer */ +struct nas_timer_t T3421; /* Detach timer */ +struct nas_timer_t T3430; /* tracking area update timer */ + +struct nas_timer_t T3423; /* E-UTRAN deactivate ISR timer */ #endif /* * -------------------------------------------------------------------------- - * EPS mobility management timers – Network side + * EPS mobility management timers – Network side * -------------------------------------------------------------------------- */ #ifdef NAS_MME -#define T3450_DEFAULT_VALUE 6 /* 6 seconds */ -#define T3460_DEFAULT_VALUE 6 /* 6 seconds */ -#define T3470_DEFAULT_VALUE 6 /* 6 seconds */ +#define T3450_DEFAULT_VALUE 6 /* 6 seconds */ +#define T3460_DEFAULT_VALUE 6 /* 6 seconds */ +#define T3470_DEFAULT_VALUE 6 /* 6 seconds */ -struct nas_timer_t T3450; /* EMM message retransmission timer */ -struct nas_timer_t T3460; /* Authentication timer */ -struct nas_timer_t T3470; /* Identification timer */ +struct nas_timer_t T3450; /* EMM message retransmission timer */ +struct nas_timer_t T3460; /* Authentication timer */ +struct nas_timer_t T3470; /* Identification timer */ /* * mobile reachable timer diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_data_ctx.c b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_data_ctx.c index 91cf130c71da562f4956caf7948c46fb947b99d8..7fadc87f6536209c007ee929a8c5118fbf4f34b9 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_data_ctx.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_data_ctx.c @@ -45,7 +45,7 @@ struct emm_data_context_s *emm_data_context_get( return RB_FIND(emm_data_context_map, &emm_data->ctx_map, &reference); } -struct emm_data_context_s * emm_data_context_remove( +struct emm_data_context_s *emm_data_context_remove( emm_data_t *emm_data, struct emm_data_context_s *elm) { return RB_REMOVE(emm_data_context_map, &emm_data->ctx_map, elm); diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.c b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.c index 6c0ad1bba1bbfb53fd15c162cb4cf5562d43f253..b9171d1d9633391fb33a88f124c889124fa775a7 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.c @@ -1,21 +1,21 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source emm_main.c +Source emm_main.c -Version 0.1 +Version 0.1 -Date 2012/10/10 +Date 2012/10/10 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines the EPS Mobility Management procedure call manager, - the main entry point for elementary EMM processing. +Description Defines the EPS Mobility Management procedure call manager, + the main entry point for elementary EMM processing. *****************************************************************************/ @@ -28,9 +28,9 @@ Description Defines the EPS Mobility Management procedure call manager, #include "usim_api.h" #include "IdleMode.h" -#include <string.h> // memset, memcpy, strlen -#include <stdio.h> // sprintf -#include <stdlib.h> // malloc, free +#include <string.h> // memset, memcpy, strlen +#include <stdio.h> // sprintf +#include <stdlib.h> // malloc, free #endif /****************************************************************************/ @@ -42,14 +42,14 @@ Description Defines the EPS Mobility Management procedure call manager, /****************************************************************************/ #ifdef NAS_UE -static int _emm_main_get_imei(imei_t* imei, const char* imei_str); +static int _emm_main_get_imei(imei_t *imei, const char *imei_str); -static int _emm_main_imsi_cmp(imsi_t* imsi1, imsi_t* imsi2); +static int _emm_main_imsi_cmp(imsi_t *imsi1, imsi_t *imsi2); -static const char* _emm_main_get_plmn(const plmn_t* plmn, int index, - int format, size_t* size); +static const char *_emm_main_get_plmn(const plmn_t *plmn, int index, + int format, size_t *size); -static int _emm_main_get_plmn_index(const char* plmn, int format); +static int _emm_main_get_plmn_index(const char *plmn, int format); /* * USIM application data @@ -71,28 +71,28 @@ static int _emm_main_callback(int); #ifdef NAS_UE /**************************************************************************** ** ** - ** Name: emm_main_initialize() ** + ** Name: emm_main_initialize() ** ** ** ** Description: Initializes EMM internal data ** ** ** - ** Inputs: cb: The user notification callback ** - ** imei: The IMEI read from the UE's non-volatile ** - ** memory ** - ** Others: _usim_data ** + ** Inputs: cb: The user notification callback ** + ** imei: The IMEI read from the UE's non-volatile ** + ** memory ** + ** Others: _usim_data ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: None ** + ** Others: _emm_data ** ** ** ***************************************************************************/ -void emm_main_initialize(emm_indication_callback_t cb, const char* imei) +void emm_main_initialize(emm_indication_callback_t cb, const char *imei) { LOG_FUNC_IN; /* USIM validity indicator */ _emm_data.usim_is_valid = FALSE; - /* The IMEI read from the UE's non-volatile memory */ - _emm_data.imei = (imei_t*)malloc(sizeof(imei_t)); + /* The IMEI read from the UE's non-volatile memory */ + _emm_data.imei = (imei_t *)malloc(sizeof(imei_t)); _emm_data.imei->length = _emm_main_get_imei(_emm_data.imei, imei); /* The IMSI, valid only if USIM is present */ _emm_data.imsi = NULL; @@ -119,9 +119,9 @@ void emm_main_initialize(emm_indication_callback_t cb, const char* imei) _emm_data.is_attached = FALSE; _emm_data.is_emergency = FALSE; /* Location/Tracking area code */ - _emm_data.tac = 0; // two byte in hexadecimal format + _emm_data.tac = 0; // two byte in hexadecimal format /* Identifier of the serving cell */ - _emm_data.ci = 0; // four byte in hexadecimal format + _emm_data.ci = 0; // four byte in hexadecimal format /* List of operators present in the network */ memset(_emm_data.plist.buffer, 0, EMM_DATA_BUFFER_SIZE + 1); /* Home PLMN */ @@ -147,172 +147,187 @@ void emm_main_initialize(emm_indication_callback_t cb, const char* imei) * Get USIM application data */ if ( usim_api_read(&_usim_data) != RETURNok ) { - /* The USIM application may not be present or not valid */ - LOG_TRACE(WARNING, "EMM-MAIN - Failed to read USIM application data"); - } - else - { - int i; - - /* The USIM application is present and valid */ - LOG_TRACE(INFO, "EMM-MAIN - USIM application data successfully read"); - _emm_data.usim_is_valid = TRUE; - - /* Get the Home PLMN derived from the IMSI */ - _emm_data.hplmn.MCCdigit1 = _usim_data.imsi.u.num.digit1; - _emm_data.hplmn.MCCdigit2 = _usim_data.imsi.u.num.digit2; - _emm_data.hplmn.MCCdigit3 = _usim_data.imsi.u.num.digit3; - _emm_data.hplmn.MNCdigit1 = _usim_data.imsi.u.num.digit4; - _emm_data.hplmn.MNCdigit2 = _usim_data.imsi.u.num.digit5; - _emm_data.hplmn.MNCdigit3 = _usim_data.imsi.u.num.digit6; - - /* Get the list of forbidden PLMNs */ - for (i=0; (i < EMM_DATA_FPLMN_MAX) && (i < USIM_FPLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.fplmn[i]) ) { - _emm_data.fplmn.plmn[i] = _usim_data.fplmn[i]; - _emm_data.fplmn.n_plmns += 1; - } - } - - /* Get the list of Equivalent HPLMNs */ - for (i=0; (i < EMM_DATA_EHPLMN_MAX) && (i < USIM_EHPLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.ehplmn[i]) ) { - _emm_data.ehplmn.plmn[i] = _usim_data.ehplmn[i]; - _emm_data.ehplmn.n_plmns += 1; - } - } - - /* Get the list of User controlled PLMN Selector */ - for (i=0; (i < EMM_DATA_PLMN_MAX) && (i < USIM_PLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.plmn[i].plmn) ) { - _emm_data.plmn.plmn[i] = _usim_data.plmn[i].plmn; - _emm_data.userAcT[i] = _usim_data.plmn[i].AcT; - _emm_data.plmn.n_plmns += 1; - } - } - - /* Get the list of Operator controlled PLMN Selector */ - for (i=0; (i < EMM_DATA_OPLMN_MAX) && (i < USIM_OPLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.oplmn[i].plmn) ) { - _emm_data.oplmn.plmn[i] = _usim_data.oplmn[i].plmn; - _emm_data.operAcT[i] = _usim_data.oplmn[i].AcT; - _emm_data.oplmn.n_plmns += 1; - } - } - - /* Get the list of Operator network name records */ - for (i=0; (i < EMM_DATA_OPNN_MAX) && (i < USIM_OPL_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.opl[i].plmn) ) { - int pnn_id = _usim_data.opl[i].record_id; - _emm_data.opnn[i].plmn = &_usim_data.opl[i].plmn; - _emm_data.opnn[i].fullname = (char*)_usim_data.pnn[pnn_id].fullname.value; - _emm_data.opnn[i].shortname = (char*)_usim_data.pnn[pnn_id].shortname.value; - _emm_data.n_opnns += 1; - } - } - - /* TODO: Get the Higher Priority PLMN search period parameter */ - - /* Get the EPS location information */ - if (PLMN_IS_VALID(_usim_data.epsloci.guti.gummei.plmn)) { - _emm_data.guti = &_usim_data.epsloci.guti; - } - if (TAI_IS_VALID(_usim_data.epsloci.tai)) { - _emm_data.tai = &_usim_data.epsloci.tai; - } - _emm_data.status = _usim_data.epsloci.status; - - /* Get NAS configuration parameters */ - _emm_data.NAS_SignallingPriority = _usim_data.nasconfig.NAS_SignallingPriority.value[0]; - _emm_data.NMO_I_Behaviour = _usim_data.nasconfig.NMO_I_Behaviour.value[0]; - _emm_data.AttachWithImsi = _usim_data.nasconfig.AttachWithImsi.value[0]; - _emm_data.MinimumPeriodicSearchTimer = _usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0]; - _emm_data.ExtendedAccessBarring = _usim_data.nasconfig.ExtendedAccessBarring.value[0]; - _emm_data.Timer_T3245_Behaviour = _usim_data.nasconfig.Timer_T3245_Behaviour.value[0]; - - /* - * Get EPS NAS security context - */ - /* Create NAS security context */ - _emm_data.security = - (emm_security_context_t*)malloc(sizeof(emm_security_context_t)); - if (_emm_data.security != NULL) { - memset(_emm_data.security, 0, sizeof(emm_security_context_t)); - /* Type of security context */ - if (_usim_data.securityctx.KSIasme.value[0] != - USIM_KSI_NOT_AVAILABLE) { - _emm_data.security->type = EMM_KSI_NATIVE; - } - else { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; - } - /* EPS key set identifier */ - _emm_data.security->eksi = _usim_data.securityctx.KSIasme.value[0]; - /* ASME security key */ - _emm_data.security->kasme.length = - _usim_data.securityctx.Kasme.length; - _emm_data.security->kasme.value = - (uint8_t*)malloc(_emm_data.security->kasme.length); - if (_emm_data.security->kasme.value) { - memcpy(_emm_data.security->kasme.value, - _usim_data.securityctx.Kasme.value, - _emm_data.security->kasme.length); - } - /* Downlink count parameter */ - if (_usim_data.securityctx.dlNAScount.length <= sizeof(UInt32_t)) { - memcpy(&_emm_data.security->dl_count, - _usim_data.securityctx.dlNAScount.value, - _usim_data.securityctx.dlNAScount.length); - } - /* Uplink count parameter */ - if (_usim_data.securityctx.ulNAScount.length <= sizeof(UInt32_t)) { - memcpy(&_emm_data.security->ul_count, - _usim_data.securityctx.ulNAScount.value, - _usim_data.securityctx.ulNAScount.length); - } - /* Ciphering algorithm */ - _emm_data.security->capability.encryption = - ((_usim_data.securityctx.algorithmID.value[0] >> 4) & 0xf); - /* Identity protection algorithm */ - _emm_data.security->capability.integrity = - (_usim_data.securityctx.algorithmID.value[0] & 0xf); - /* NAS integrity and cyphering keys are not available */ - } - else { - LOG_TRACE(WARNING, - "EMM-PROC - Failed to create security context"); - } - - /* - * Get EMM data from the UE's non-volatile memory - */ - memset(&_emm_data.nvdata.rplmn, 0xFF, sizeof(plmn_t)); - _emm_data.nvdata.eplmn.n_plmns = 0; - /* Get EMM data pathname */ - char* path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); - if (path == NULL) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to get EMM data pathname"); - } - else { - /* Get EMM data stored in the non-volatile memory device */ - int rc = memory_read(path, &_emm_data.nvdata, sizeof(emm_nvdata_t)); - if (rc != RETURNok) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to read %s", path); - } - else { - /* Check the IMSI */ - LOG_TRACE(INFO, "EMM-MAIN - EMM data successfully read"); - _emm_data.imsi = &_usim_data.imsi; - int imsi_ok = _emm_main_imsi_cmp(&_emm_data.nvdata.imsi, - &_usim_data.imsi); - if (!imsi_ok) { - LOG_TRACE(WARNING, "EMM-MAIN - IMSI checking failed"); - memset(&_emm_data.nvdata.rplmn, 0xFF, sizeof(plmn_t)); - _emm_data.nvdata.eplmn.n_plmns = 0; - } - } - free(path); - } + /* The USIM application may not be present or not valid */ + LOG_TRACE(WARNING, "EMM-MAIN - Failed to read USIM application data"); + } else { + int i; + + /* The USIM application is present and valid */ + LOG_TRACE(INFO, "EMM-MAIN - USIM application data successfully read"); + _emm_data.usim_is_valid = TRUE; + + /* Get the Home PLMN derived from the IMSI */ + _emm_data.hplmn.MCCdigit1 = _usim_data.imsi.u.num.digit1; + _emm_data.hplmn.MCCdigit2 = _usim_data.imsi.u.num.digit2; + _emm_data.hplmn.MCCdigit3 = _usim_data.imsi.u.num.digit3; + _emm_data.hplmn.MNCdigit1 = _usim_data.imsi.u.num.digit4; + _emm_data.hplmn.MNCdigit2 = _usim_data.imsi.u.num.digit5; + _emm_data.hplmn.MNCdigit3 = _usim_data.imsi.u.num.digit6; + + /* Get the list of forbidden PLMNs */ + for (i=0; (i < EMM_DATA_FPLMN_MAX) && (i < USIM_FPLMN_MAX); i++) { + if ( PLMN_IS_VALID(_usim_data.fplmn[i]) ) { + _emm_data.fplmn.plmn[i] = _usim_data.fplmn[i]; + _emm_data.fplmn.n_plmns += 1; + } + } + + /* Get the list of Equivalent HPLMNs */ + for (i=0; (i < EMM_DATA_EHPLMN_MAX) && (i < USIM_EHPLMN_MAX); i++) { + if ( PLMN_IS_VALID(_usim_data.ehplmn[i]) ) { + _emm_data.ehplmn.plmn[i] = _usim_data.ehplmn[i]; + _emm_data.ehplmn.n_plmns += 1; + } + } + + /* Get the list of User controlled PLMN Selector */ + for (i=0; (i < EMM_DATA_PLMN_MAX) && (i < USIM_PLMN_MAX); i++) { + if ( PLMN_IS_VALID(_usim_data.plmn[i].plmn) ) { + _emm_data.plmn.plmn[i] = _usim_data.plmn[i].plmn; + _emm_data.userAcT[i] = _usim_data.plmn[i].AcT; + _emm_data.plmn.n_plmns += 1; + } + } + + /* Get the list of Operator controlled PLMN Selector */ + for (i=0; (i < EMM_DATA_OPLMN_MAX) && (i < USIM_OPLMN_MAX); i++) { + if ( PLMN_IS_VALID(_usim_data.oplmn[i].plmn) ) { + _emm_data.oplmn.plmn[i] = _usim_data.oplmn[i].plmn; + _emm_data.operAcT[i] = _usim_data.oplmn[i].AcT; + _emm_data.oplmn.n_plmns += 1; + } + } + + /* Get the list of Operator network name records */ + for (i=0; (i < EMM_DATA_OPNN_MAX) && (i < USIM_OPL_MAX); i++) { + if ( PLMN_IS_VALID(_usim_data.opl[i].plmn) ) { + int pnn_id = _usim_data.opl[i].record_id; + _emm_data.opnn[i].plmn = &_usim_data.opl[i].plmn; + _emm_data.opnn[i].fullname = (char *)_usim_data.pnn[pnn_id].fullname.value; + _emm_data.opnn[i].shortname = (char *)_usim_data.pnn[pnn_id].shortname.value; + _emm_data.n_opnns += 1; + } + } + + /* TODO: Get the Higher Priority PLMN search period parameter */ + + /* Get the EPS location information */ + if (PLMN_IS_VALID(_usim_data.epsloci.guti.gummei.plmn)) { + _emm_data.guti = &_usim_data.epsloci.guti; + } + if (TAI_IS_VALID(_usim_data.epsloci.tai)) { + _emm_data.tai = &_usim_data.epsloci.tai; + } + _emm_data.status = _usim_data.epsloci.status; + + /* Get NAS configuration parameters */ + _emm_data.NAS_SignallingPriority = + _usim_data.nasconfig.NAS_SignallingPriority.value[0]; + _emm_data.NMO_I_Behaviour = _usim_data.nasconfig.NMO_I_Behaviour.value[0]; + _emm_data.AttachWithImsi = _usim_data.nasconfig.AttachWithImsi.value[0]; + _emm_data.MinimumPeriodicSearchTimer = + _usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0]; + _emm_data.ExtendedAccessBarring = + _usim_data.nasconfig.ExtendedAccessBarring.value[0]; + _emm_data.Timer_T3245_Behaviour = + _usim_data.nasconfig.Timer_T3245_Behaviour.value[0]; + + /* + * Get EPS NAS security context + */ + /* Create NAS security context */ + _emm_data.security = + (emm_security_context_t *)malloc(sizeof(emm_security_context_t)); + if (_emm_data.security != NULL) { + memset(_emm_data.security, 0, sizeof(emm_security_context_t)); + /* Type of security context */ + if (_usim_data.securityctx.KSIasme.value[0] != + USIM_KSI_NOT_AVAILABLE) { + _emm_data.security->type = EMM_KSI_NATIVE; + } else { + _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + } + /* EPS key set identifier */ + _emm_data.security->eksi = _usim_data.securityctx.KSIasme.value[0]; + /* ASME security key */ + _emm_data.security->kasme.length = + _usim_data.securityctx.Kasme.length; + _emm_data.security->kasme.value = + (uint8_t *)malloc(_emm_data.security->kasme.length); + if (_emm_data.security->kasme.value) { + memcpy(_emm_data.security->kasme.value, + _usim_data.securityctx.Kasme.value, + _emm_data.security->kasme.length); + } + /* Downlink count parameter */ + if (_usim_data.securityctx.dlNAScount.length <= sizeof(UInt32_t)) { + memcpy(&_emm_data.security->dl_count, + _usim_data.securityctx.dlNAScount.value, + _usim_data.securityctx.dlNAScount.length); + } + /* Uplink count parameter */ + if (_usim_data.securityctx.ulNAScount.length <= sizeof(UInt32_t)) { + memcpy(&_emm_data.security->ul_count, + _usim_data.securityctx.ulNAScount.value, + _usim_data.securityctx.ulNAScount.length); + } + /* Ciphering algorithm */ + _emm_data.security->capability.encryption = + ((_usim_data.securityctx.algorithmID.value[0] >> 4) & 0xf); + /* Identity protection algorithm */ + _emm_data.security->capability.integrity = + (_usim_data.securityctx.algorithmID.value[0] & 0xf); + /* NAS integrity and cyphering keys are not available */ + } else { + LOG_TRACE(WARNING, + "EMM-PROC - Failed to create security context"); + } + + /* + * Get EMM data from the UE's non-volatile memory + */ + memset(&_emm_data.nvdata.rplmn, 0xFF, sizeof(plmn_t)); + _emm_data.nvdata.eplmn.n_plmns = 0; + /* Get EMM data pathname */ + char *path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); + if (path == NULL) { + LOG_TRACE(ERROR, "EMM-MAIN - Failed to get EMM data pathname"); + } else { + /* Get EMM data stored in the non-volatile memory device */ + int rc = memory_read(path, &_emm_data.nvdata, sizeof(emm_nvdata_t)); + if (rc != RETURNok) { + LOG_TRACE(ERROR, "EMM-MAIN - Failed to read %s", path); + } else { + /* Check the IMSI */ + LOG_TRACE(INFO, "EMM-MAIN - EMM data successfully read"); + _emm_data.imsi = &_usim_data.imsi; + int imsi_ok = _emm_main_imsi_cmp(&_emm_data.nvdata.imsi, + &_usim_data.imsi); + if (!imsi_ok) { + LOG_TRACE(WARNING, "EMM-MAIN - IMSI checking failed nvram: " + "%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x, " + "usim: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x", + _emm_data.nvdata.imsi.u.value[0], + _emm_data.nvdata.imsi.u.value[1], + _emm_data.nvdata.imsi.u.value[2], + _emm_data.nvdata.imsi.u.value[3], + _emm_data.nvdata.imsi.u.value[4], + _emm_data.nvdata.imsi.u.value[5], + _emm_data.nvdata.imsi.u.value[6], + _emm_data.nvdata.imsi.u.value[7], + _usim_data.imsi.u.value[0], + _usim_data.imsi.u.value[1], + _usim_data.imsi.u.value[2], + _usim_data.imsi.u.value[3], + _usim_data.imsi.u.value[4], + _usim_data.imsi.u.value[5], + _usim_data.imsi.u.value[6], _usim_data.imsi.u.value[7]); + memset(&_emm_data.nvdata.rplmn, 0xFF, sizeof(plmn_t)); + _emm_data.nvdata.eplmn.n_plmns = 0; + } + } + free(path); + } } /* @@ -355,16 +370,16 @@ void emm_main_initialize(emm_indication_callback_t cb, const char* imei) #ifdef NAS_MME /**************************************************************************** ** ** - ** Name: emm_main_initialize() ** + ** Name: emm_main_initialize() ** ** ** ** Description: Initializes EMM internal data ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: None ** + ** Others: _emm_data ** ** ** ***************************************************************************/ void emm_main_initialize(void) @@ -373,7 +388,7 @@ void emm_main_initialize(void) /* Retreive MME supported configuration data */ if (mme_api_get_emm_config(&_emm_data.conf) != RETURNok) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to get MME configuration data"); + LOG_TRACE(ERROR, "EMM-MAIN - Failed to get MME configuration data"); } #if defined(EPC_BUILD) @@ -396,16 +411,16 @@ void emm_main_initialize(void) /**************************************************************************** ** ** - ** Name: emm_main_cleanup() ** + ** Name: emm_main_cleanup() ** ** ** ** Description: Performs the EPS Mobility Management clean up procedure ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ void emm_main_cleanup(void) @@ -415,47 +430,44 @@ void emm_main_cleanup(void) #ifdef NAS_UE if (_emm_data.usim_is_valid) { - /* - * TODO: Update USIM application data - */ + /* + * TODO: Update USIM application data + */ #if 0 - int i; - /* Update the list of Forbidden PLMNs */ - for (i=0; (i < _emm_data.fplmn.n_plmns) && (i < USIM_FPLMN_MAX); i++) - { - _usim_data.fplmn[i] = _emm_data.fplmn.plmn[i]; - } - /* Update the list of Equivalent HPLMNs */ - for (i=0; (i < _emm_data.ehplmn.n_plmns) && (i < USIM_EHPLMN_MAX); i++) - { - _usim_data.ehplmn[i] = _emm_data.ehplmn.plmn[i]; - } - /* Update the GUTI */ - if (_emm_data.guti) { - _usim_data.epsloci.guti = *(_emm_data.guti); - } - /* Update the last visited registered TAI */ - if (_emm_data.tai) { - _usim_data.epsloci.tai = *(_emm_data.tai); - } - /* Update the EPS location information */ - _usim_data.epsloci.status = _emm_data.status; - - if (_emm_data.security && (_emm_data.security->type == EMM_KSI_NATIVE)) - { - /* TODO: Update the EPS security context parameters from the full - * native EPS security context */ - } - - /* - * Store USIM application data - * - List of forbidden PLMNs - */ - if ( usim_api_write(&_usim_data) != RETURNok ) { - /* The USIM application may not be present or not valid */ - LOG_TRACE(WARNING, "EMM-MAIN - " - "Failed to write USIM application data"); - } + int i; + /* Update the list of Forbidden PLMNs */ + for (i=0; (i < _emm_data.fplmn.n_plmns) && (i < USIM_FPLMN_MAX); i++) { + _usim_data.fplmn[i] = _emm_data.fplmn.plmn[i]; + } + /* Update the list of Equivalent HPLMNs */ + for (i=0; (i < _emm_data.ehplmn.n_plmns) && (i < USIM_EHPLMN_MAX); i++) { + _usim_data.ehplmn[i] = _emm_data.ehplmn.plmn[i]; + } + /* Update the GUTI */ + if (_emm_data.guti) { + _usim_data.epsloci.guti = *(_emm_data.guti); + } + /* Update the last visited registered TAI */ + if (_emm_data.tai) { + _usim_data.epsloci.tai = *(_emm_data.tai); + } + /* Update the EPS location information */ + _usim_data.epsloci.status = _emm_data.status; + + if (_emm_data.security && (_emm_data.security->type == EMM_KSI_NATIVE)) { + /* TODO: Update the EPS security context parameters from the full + * native EPS security context */ + } + + /* + * Store USIM application data + * - List of forbidden PLMNs + */ + if ( usim_api_write(&_usim_data) != RETURNok ) { + /* The USIM application may not be present or not valid */ + LOG_TRACE(WARNING, "EMM-MAIN - " + "Failed to write USIM application data"); + } #endif } @@ -464,29 +476,34 @@ void emm_main_cleanup(void) * - Registered PLMN * - List of equivalent PLMNs */ - char* path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); + char *path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); if (path == NULL) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to get EMM data pathname"); - } - else { - int rc = memory_write(path, &_emm_data.nvdata, sizeof(emm_nvdata_t)); - if (rc != RETURNok) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to write %s", path); - } + LOG_TRACE(ERROR, "EMM-MAIN - Failed to get EMM data pathname"); + } else { + int rc = memory_write(path, &_emm_data.nvdata, sizeof(emm_nvdata_t)); + if (rc != RETURNok) { + LOG_TRACE(ERROR, "EMM-MAIN - Failed to write %s", path); + } } /* Release dynamically allocated memory */ if (_emm_data.imei) { - free(_emm_data.imei); - _emm_data.imei = NULL; + free(_emm_data.imei); + _emm_data.imei = NULL; } if (_emm_data.security) { - emm_security_context_t* security = _emm_data.security; - if (security->kasme.value) free(security->kasme.value); - if (security->knas_enc.value) free(security->knas_enc.value); - if (security->knas_int.value) free(security->knas_int.value); - free(_emm_data.security); - _emm_data.security = NULL; + emm_security_context_t *security = _emm_data.security; + if (security->kasme.value) { + free(security->kasme.value); + } + if (security->knas_enc.value) { + free(security->knas_enc.value); + } + if (security->knas_int.value) { + free(security->knas_int.value); + } + free(_emm_data.security); + _emm_data.security = NULL; } #endif // NAS_UE @@ -497,19 +514,19 @@ void emm_main_cleanup(void) #ifdef NAS_UE /**************************************************************************** ** ** - ** Name: emm_main_get_imsi() ** + ** Name: emm_main_get_imsi() ** ** ** ** Description: Get the International Mobile Subscriber Identity number ** ** ** - ** Inputs: None ** - ** Others: _emm_data ** + ** Inputs: None ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: Pointer to the IMSI ** - ** Others: None ** + ** Outputs: None ** + ** Return: Pointer to the IMSI ** + ** Others: None ** ** ** ***************************************************************************/ -const imsi_t* emm_main_get_imsi(void) +const imsi_t *emm_main_get_imsi(void) { LOG_FUNC_IN; LOG_FUNC_RETURN (&_emm_data.nvdata.imsi); @@ -517,19 +534,19 @@ const imsi_t* emm_main_get_imsi(void) /**************************************************************************** ** ** - ** Name: emm_main_get_msisdn() ** + ** Name: emm_main_get_msisdn() ** ** ** ** Description: Get the Mobile Subscriber Dialing Number from the USIM ** ** ** - ** Inputs: None ** - ** Others: _usim_data ** + ** Inputs: None ** + ** Others: _usim_data ** ** ** - ** Outputs: None ** - ** Return: Pointer to the subscriber dialing number ** - ** Others: None ** + ** Outputs: None ** + ** Return: Pointer to the subscriber dialing number ** + ** Others: None ** ** ** ***************************************************************************/ -const msisdn_t* emm_main_get_msisdn(void) +const msisdn_t *emm_main_get_msisdn(void) { LOG_FUNC_IN; LOG_FUNC_RETURN (&_usim_data.msisdn.number); @@ -537,57 +554,55 @@ const msisdn_t* emm_main_get_msisdn(void) /**************************************************************************** ** ** - ** Name: emm_main_set_plmn_selection_mode() ** + ** Name: emm_main_set_plmn_selection_mode() ** ** ** ** Description: Set the network selection mode of operation to the given ** - ** mode and update the manually selected network selection ** - ** data ** + ** mode and update the manually selected network selection ** + ** data ** ** ** - ** Inputs: mode: The specified network selection mode of ** - ** operation ** - ** format: The representation format of the PLMN ** - ** identifier ** - ** plmn: Identifier of the selected PLMN ** - ** rat: The selected Radio Access Techonology ** - ** Others: None ** + ** Inputs: mode: The specified network selection mode of ** + ** operation ** + ** format: The representation format of the PLMN ** + ** identifier ** + ** plmn: Identifier of the selected PLMN ** + ** rat: The selected Radio Access Techonology ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ int emm_main_set_plmn_selection_mode(int mode, int format, - const network_plmn_t* plmn, int rat) + const network_plmn_t *plmn, int rat) { LOG_FUNC_IN; int index; LOG_TRACE(INFO, "EMM-MAIN - PLMN selection: mode=%d, format=%d, plmn=%s, " - "rat=%d", mode, format, (const char*)&plmn->id, rat); + "rat=%d", mode, format, (const char *)&plmn->id, rat); _emm_data.plmn_mode = mode; if (mode != EMM_DATA_PLMN_AUTO) { - /* Get the index of the PLMN in the list of available PLMNs */ - index = _emm_main_get_plmn_index((const char*)&plmn->id, format); - if (index < 0) { - LOG_TRACE(WARNING, "EMM-MAIN - PLMN %s not available", - (const char*)&plmn->id); - } - else { - /* Update the manually selected network selection data */ - _emm_data.plmn_index = index; - _emm_data.plmn_rat = rat; - } - } - else { - /* - * Get the index of the last PLMN the UE already tried to automatically - * register to when switched on; the equivalent PLMNs list shall not be - * applied to the user reselection in Automatic Network Selection Mode. - */ - index = IdleMode_get_hplmn_index(); + /* Get the index of the PLMN in the list of available PLMNs */ + index = _emm_main_get_plmn_index((const char *)&plmn->id, format); + if (index < 0) { + LOG_TRACE(WARNING, "EMM-MAIN - PLMN %s not available", + (const char *)&plmn->id); + } else { + /* Update the manually selected network selection data */ + _emm_data.plmn_index = index; + _emm_data.plmn_rat = rat; + } + } else { + /* + * Get the index of the last PLMN the UE already tried to automatically + * register to when switched on; the equivalent PLMNs list shall not be + * applied to the user reselection in Automatic Network Selection Mode. + */ + index = IdleMode_get_hplmn_index(); } LOG_FUNC_RETURN (index); @@ -595,17 +610,17 @@ int emm_main_set_plmn_selection_mode(int mode, int format, /**************************************************************************** ** ** - ** Name: emm_main_get_plmn_selection_mode() ** + ** Name: emm_main_get_plmn_selection_mode() ** ** ** ** Description: Get the current value of the network selection mode of ** - ** operation ** + ** operation ** ** ** - ** Inputs: None ** - ** Others: _emm_data ** + ** Inputs: None ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: The value of the network selection mode ** - ** Others: None ** + ** Outputs: None ** + ** Return: The value of the network selection mode ** + ** Others: None ** ** ** ***************************************************************************/ int emm_main_get_plmn_selection_mode(void) @@ -616,19 +631,19 @@ int emm_main_get_plmn_selection_mode(void) /**************************************************************************** ** ** - ** Name: emm_main_get_plmn_list() ** + ** Name: emm_main_get_plmn_list() ** ** ** ** Description: Get the list of available PLMNs ** ** ** - ** Inputs: None ** - ** Others: _emm_data ** + ** Inputs: None ** + ** Others: _emm_data ** ** ** - ** Outputs: plist: Pointer to the list of available PLMNs ** - ** Return: The size of the list in bytes ** - ** Others: None ** + ** Outputs: plist: Pointer to the list of available PLMNs ** + ** Return: The size of the list in bytes ** + ** Others: None ** ** ** ***************************************************************************/ -int emm_main_get_plmn_list(const char** plist) +int emm_main_get_plmn_list(const char **plist) { LOG_FUNC_IN; @@ -640,22 +655,22 @@ int emm_main_get_plmn_list(const char** plist) /**************************************************************************** ** ** - ** Name: emm_main_get_selected_plmn() ** + ** Name: emm_main_get_selected_plmn() ** ** ** ** Description: Get the identifier of the currently selected PLMN ** ** ** - ** Inputs: format: The requested format of the string repre- ** - ** sentation of the PLMN identifier ** - ** Others: _emm_data ** + ** Inputs: format: The requested format of the string repre- ** + ** sentation of the PLMN identifier ** + ** Others: _emm_data ** ** ** - ** Outputs: plmn: The selected PLMN identifier coded in the ** - ** requested format ** - ** Return: A pointer to the string representation of ** - ** the selected PLMN ** - ** Others: None ** + ** Outputs: plmn: The selected PLMN identifier coded in the ** + ** requested format ** + ** Return: A pointer to the string representation of ** + ** the selected PLMN ** + ** Others: None ** ** ** ***************************************************************************/ -const char* emm_main_get_selected_plmn(network_plmn_t* plmn, int format) +const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format) { LOG_FUNC_IN; @@ -665,11 +680,11 @@ const char* emm_main_get_selected_plmn(network_plmn_t* plmn, int format) */ int index = IdleMode_get_splmn_index(); if ( !(index < 0) ) { - const char* name = _emm_main_get_plmn(&_emm_data.splmn, index, - format, &size); - if (size > 0) { - LOG_FUNC_RETURN ((char*) memcpy(&plmn->id, name, size)); - } + const char *name = _emm_main_get_plmn(&_emm_data.splmn, index, + format, &size); + if (size > 0) { + LOG_FUNC_RETURN ((char *) memcpy(&plmn->id, name, size)); + } } LOG_FUNC_RETURN (NULL); @@ -677,22 +692,22 @@ const char* emm_main_get_selected_plmn(network_plmn_t* plmn, int format) /**************************************************************************** ** ** - ** Name: emm_main_get_registered_plmn() ** + ** Name: emm_main_get_registered_plmn() ** ** ** ** Description: Get the identifier of the currently registered PLMN ** ** ** - ** Inputs: format: The requested format of the string repre- ** - ** sentation of the PLMN identifier ** - ** Others: _emm_data ** + ** Inputs: format: The requested format of the string repre- ** + ** sentation of the PLMN identifier ** + ** Others: _emm_data ** ** ** - ** Outputs: plmn: The registered PLMN identifier coded in ** - ** the requested format ** - ** Return: A pointer to the string representation of ** - ** the registered PLMN ** - ** Others: None ** + ** Outputs: plmn: The registered PLMN identifier coded in ** + ** the requested format ** + ** Return: A pointer to the string representation of ** + ** the registered PLMN ** + ** Others: None ** ** ** ***************************************************************************/ -const char* emm_main_get_registered_plmn(network_plmn_t* plmn, int format) +const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format) { LOG_FUNC_IN; @@ -703,11 +718,11 @@ const char* emm_main_get_registered_plmn(network_plmn_t* plmn, int format) */ int index = IdleMode_get_rplmn_index(); if ( !(index < 0) ) { - const char* name = _emm_main_get_plmn(&_emm_data.nvdata.rplmn, - index, format, &size); - if (size > 0) { - LOG_FUNC_RETURN ((char*) memcpy(&plmn->id, name, size)); - } + const char *name = _emm_main_get_plmn(&_emm_data.nvdata.rplmn, + index, format, &size); + if (size > 0) { + LOG_FUNC_RETURN ((char *) memcpy(&plmn->id, name, size)); + } } LOG_FUNC_RETURN (NULL); @@ -715,18 +730,18 @@ const char* emm_main_get_registered_plmn(network_plmn_t* plmn, int format) /**************************************************************************** ** ** - ** Name: emm_main_get_plmn_status() ** + ** Name: emm_main_get_plmn_status() ** ** ** ** Description: Get the value of the network registration status which ** - ** shows whether the network has currently indicated the ** - ** registration of the UE ** + ** shows whether the network has currently indicated the ** + ** registration of the UE ** ** ** - ** Inputs: None ** - ** Others: _emm_data ** + ** Inputs: None ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: The current network registration status ** - ** Others: None ** + ** Outputs: None ** + ** Return: The current network registration status ** + ** Others: None ** ** ** ***************************************************************************/ Stat_t emm_main_get_plmn_status(void) @@ -737,17 +752,17 @@ Stat_t emm_main_get_plmn_status(void) /**************************************************************************** ** ** - ** Name: emm_main_get_plmn_tac() ** + ** Name: emm_main_get_plmn_tac() ** ** ** ** Description: Get the code of the Tracking area the registered PLMN ** - ** belongs to ** + ** belongs to ** ** ** - ** Inputs: None ** - ** Others: _emm_data ** + ** Inputs: None ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: The Location/Tracking area code ** - ** Others: None ** + ** Outputs: None ** + ** Return: The Location/Tracking area code ** + ** Others: None ** ** ** ***************************************************************************/ tac_t emm_main_get_plmn_tac(void) @@ -758,16 +773,16 @@ tac_t emm_main_get_plmn_tac(void) /**************************************************************************** ** ** - ** Name: emm_main_get_plmn_ci() ** + ** Name: emm_main_get_plmn_ci() ** ** ** ** Description: Get the identifier of the serving cell ** ** ** - ** Inputs: None ** - ** Others: _emm_data ** + ** Inputs: None ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: The serving cell identifier ** - ** Others: None ** + ** Outputs: None ** + ** Return: The serving cell identifier ** + ** Others: None ** ** ** ***************************************************************************/ ci_t emm_main_get_plmn_ci(void) @@ -778,18 +793,18 @@ ci_t emm_main_get_plmn_ci(void) /**************************************************************************** ** ** - ** Name: emm_main_get_plmn_rat() ** + ** Name: emm_main_get_plmn_rat() ** ** ** ** Description: Get the value of the Radio Access Technology of the ser- ** - ** ving cell ** + ** ving cell ** ** ** - ** Inputs: None ** - ** Others: _emm_data ** + ** Inputs: None ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: The value of the Radio Access Technology ** - ** of the serving cell ** - ** Others: None ** + ** Outputs: None ** + ** Return: The value of the Radio Access Technology ** + ** of the serving cell ** + ** Others: None ** ** ** ***************************************************************************/ AcT_t emm_main_get_plmn_rat(void) @@ -800,18 +815,18 @@ AcT_t emm_main_get_plmn_rat(void) /**************************************************************************** ** ** - ** Name: emm_main_is_attached() ** + ** Name: emm_main_is_attached() ** ** ** ** Description: Indicates whether the UE is currently attached to the ** - ** network for EPS services or emergency service only ** + ** network for EPS services or emergency service only ** ** ** - ** Inputs: None ** - ** Others: _emm_data ** + ** Inputs: None ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: TRUE if the UE is currently attached to ** - ** the network; FALSE otherwise. ** - ** Others: None ** + ** Outputs: None ** + ** Return: TRUE if the UE is currently attached to ** + ** the network; FALSE otherwise. ** + ** Others: None ** ** ** ***************************************************************************/ int emm_main_is_attached(void) @@ -822,19 +837,19 @@ int emm_main_is_attached(void) /**************************************************************************** ** ** - ** Name: emm_main_get_plmn_rat() ** + ** Name: emm_main_get_plmn_rat() ** ** ** ** Description: Indicates whether the UE is currently attached to the ** - ** network for emergency bearer services ** + ** network for emergency bearer services ** ** ** - ** Inputs: None ** - ** Others: _emm_data ** + ** Inputs: None ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: TRUE if the UE is currently attached or is ** - ** attempting to attach to the network for ** - ** emergency bearer services; FALSE otherwise ** - ** Others: None ** + ** Outputs: None ** + ** Return: TRUE if the UE is currently attached or is ** + ** attempting to attach to the network for ** + ** emergency bearer services; FALSE otherwise ** + ** Others: None ** ** ** ***************************************************************************/ int emm_main_is_emergency(void) @@ -851,21 +866,21 @@ int emm_main_is_emergency(void) #ifdef NAS_UE /**************************************************************************** ** ** - ** Name: _emm_main_callback() ** + ** Name: _emm_main_callback() ** ** ** ** Description: Forwards the network indication to the upper control la- ** - ** yer (user API) to notify that network registration and/or ** - ** location information has changed. ** + ** yer (user API) to notify that network registration and/or ** + ** location information has changed. ** ** ** - ** Inputs: size: Size in byte of the list of operators ** - ** present in the network. The list has to be ** - ** displayed to the user application when ** - ** size > 0. ** - ** Others: _emm_data ** + ** Inputs: size: Size in byte of the list of operators ** + ** present in the network. The list has to be ** + ** displayed to the user application when ** + ** size > 0. ** + ** Others: _emm_data ** ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok, RETURNerror ** + ** Others: None ** ** ** ***************************************************************************/ static int _emm_main_callback(int size) @@ -874,34 +889,34 @@ static int _emm_main_callback(int size) /* Forward the notification to the user API */ int rc = (*_emm_main_user_callback)(_emm_data.stat, _emm_data.tac, - _emm_data.ci, _emm_data.rat, - _emm_data.plist.buffer, size); + _emm_data.ci, _emm_data.rat, + _emm_data.plist.buffer, size); LOG_FUNC_RETURN (rc); } /**************************************************************************** ** ** - ** Name: _emm_main_get_imei() ** + ** Name: _emm_main_get_imei() ** ** ** ** Description: Returns the International Mobile Equipment Identity con- ** - ** tained in the given string representation ** + ** tained in the given string representation ** ** ** - ** Inputs: imei: The string representation of the IMEI ** - ** Others: None ** + ** Inputs: imei: The string representation of the IMEI ** + ** Others: None ** ** ** - ** Outputs: imei: The IMEI of the UE ** - ** Return: The number of digits in the IMEI ** - ** Others: None ** + ** Outputs: imei: The IMEI of the UE ** + ** Return: The number of digits in the IMEI ** + ** Others: None ** ** ** ***************************************************************************/ -static int _emm_main_get_imei(imei_t* imei, const char* imei_str) +static int _emm_main_get_imei(imei_t *imei, const char *imei_str) { int len = strlen(imei_str); if (len % 2) { - imei->u.num.parity = ODD_PARITY; + imei->u.num.parity = ODD_PARITY; } else { - imei->u.num.parity = EVEN_PARITY; + imei->u.num.parity = EVEN_PARITY; } imei->u.num.digit1 = imei_str[0] - '0'; imei->u.num.digit2 = imei_str[1] - '0'; @@ -923,125 +938,123 @@ static int _emm_main_get_imei(imei_t* imei, const char* imei_str) /**************************************************************************** ** ** - ** Name: _emm_main_imsi_cmp() ** + ** Name: _emm_main_imsi_cmp() ** ** ** ** Description: Compares two International Mobile Subscriber Identifiers ** ** ** - ** Inputs: imsi1: The first IMSI ** - ** imsi2: The second IMSI to compare to ** - ** Others: None ** + ** Inputs: imsi1: The first IMSI ** + ** imsi2: The second IMSI to compare to ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: TRUE if the first IMSI is found to match ** - ** the second; FALSE otherwise. ** - ** Others: None ** + ** Outputs: None ** + ** Return: TRUE if the first IMSI is found to match ** + ** the second; FALSE otherwise. ** + ** Others: None ** ** ** ***************************************************************************/ -static int _emm_main_imsi_cmp(imsi_t* imsi1, imsi_t* imsi2) +static int _emm_main_imsi_cmp(imsi_t *imsi1, imsi_t *imsi2) { if (imsi1->length != imsi2->length) { - return FALSE; + return FALSE; } for (int i = 0; i < imsi1->length; i++) { - if (imsi1->u.value[i] != imsi2->u.value[i]) { - return FALSE; - } + if (imsi1->u.value[i] != imsi2->u.value[i]) { + return FALSE; + } } return TRUE; } /**************************************************************************** ** ** - ** Name: _emm_main_get_plmn() ** + ** Name: _emm_main_get_plmn() ** ** ** ** Description: Get the identifier of the PLMN at the given index in the ** - ** list of available PLMNs. ** + ** list of available PLMNs. ** ** ** - ** Inputs: plmn: The PLMN to search for ** - ** index: The index of the PLMN in the list of PLMNs ** - ** format: The requested representation format of the ** - ** PLMN identifier ** - ** Others: None ** + ** Inputs: plmn: The PLMN to search for ** + ** index: The index of the PLMN in the list of PLMNs ** + ** format: The requested representation format of the ** + ** PLMN identifier ** + ** Others: None ** ** ** - ** Outputs: size: The size in bytes of the PLMN identifier ** - ** coded in the requested format ** - ** Return: A pointer to the identifier of the PLMN ** - ** Others: None ** + ** Outputs: size: The size in bytes of the PLMN identifier ** + ** coded in the requested format ** + ** Return: A pointer to the identifier of the PLMN ** + ** Others: None ** ** ** ***************************************************************************/ -static const char* _emm_main_get_plmn(const plmn_t* plmn, int index, - int format, size_t* size) +static const char *_emm_main_get_plmn(const plmn_t *plmn, int index, + int format, size_t *size) { if ( PLMN_IS_VALID(*plmn) ) { - switch (format) - { - case NET_FORMAT_LONG: - /* Get the long alpha-numeric representation of the PLMN */ - return IdleMode_get_plmn_fullname(plmn, index, size); - break; - - case NET_FORMAT_SHORT: - /* Get the short alpha-numeric representation of the PLMN */ - return IdleMode_get_plmn_shortname(plmn, index, size); - break; - - case NET_FORMAT_NUM: - /* Get the numeric representation of the PLMN */ - return IdleMode_get_plmn_id(plmn, index, size); - break; - - default: - LOG_TRACE(WARNING, "EMM-MAIN - Format is not valid (%d)", - format); - *size = 0; - break; - } + switch (format) { + case NET_FORMAT_LONG: + /* Get the long alpha-numeric representation of the PLMN */ + return IdleMode_get_plmn_fullname(plmn, index, size); + break; + + case NET_FORMAT_SHORT: + /* Get the short alpha-numeric representation of the PLMN */ + return IdleMode_get_plmn_shortname(plmn, index, size); + break; + + case NET_FORMAT_NUM: + /* Get the numeric representation of the PLMN */ + return IdleMode_get_plmn_id(plmn, index, size); + break; + + default: + LOG_TRACE(WARNING, "EMM-MAIN - Format is not valid (%d)", + format); + *size = 0; + break; + } } return (NULL); } /**************************************************************************** ** ** - ** Name: _emm_main_get_plmn_index() ** + ** Name: _emm_main_get_plmn_index() ** ** ** ** Description: Get the index of the given PLMN in the ordered list of ** - ** available PLMNs ** + ** available PLMNs ** ** ** - ** Inputs: plmn: Identifier of the PLMN ** - ** format: The representation format of the PLMN ** - ** identifier ** - ** Others: None ** + ** Inputs: plmn: Identifier of the PLMN ** + ** format: The representation format of the PLMN ** + ** identifier ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: The index of the selected PLMN in the list ** - ** of available PLMNs; -1 if the PLMN is not ** - ** found ** - ** Others: None ** + ** Outputs: None ** + ** Return: The index of the selected PLMN in the list ** + ** of available PLMNs; -1 if the PLMN is not ** + ** found ** + ** Others: None ** ** ** ***************************************************************************/ -static int _emm_main_get_plmn_index(const char* plmn, int format) +static int _emm_main_get_plmn_index(const char *plmn, int format) { int index = -1; - switch (format) - { - case NET_FORMAT_LONG: - /* Get the index of the long alpha-numeric PLMN identifier */ - index = IdleMode_get_plmn_fullname_index(plmn); - break; - - case NET_FORMAT_SHORT: - /* Get the index of the short alpha-numeric PLMN identifier */ - index = IdleMode_get_plmn_shortname_index(plmn); - break; - - case NET_FORMAT_NUM: - /* Get the index of the numeric PLMN identifier */ - index = IdleMode_get_plmn_id_index(plmn); - break; - - default: - LOG_TRACE(WARNING, "EMM-MAIN - Format is not valid (%d)", format); - break; + switch (format) { + case NET_FORMAT_LONG: + /* Get the index of the long alpha-numeric PLMN identifier */ + index = IdleMode_get_plmn_fullname_index(plmn); + break; + + case NET_FORMAT_SHORT: + /* Get the index of the short alpha-numeric PLMN identifier */ + index = IdleMode_get_plmn_shortname_index(plmn); + break; + + case NET_FORMAT_NUM: + /* Get the index of the numeric PLMN identifier */ + index = IdleMode_get_plmn_id_index(plmn); + break; + + default: + LOG_TRACE(WARNING, "EMM-MAIN - Format is not valid (%d)", format); + break; } return (index); } diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.h b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.h index 668e1a76ca8c0ef73c1c56928472d19afbd5b86f..eae046373ffedeacf6e7cebf0471f9a73dcfbd9c 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.h +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.h @@ -1,21 +1,21 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source emm_main.h +Source emm_main.h -Version 0.1 +Version 0.1 -Date 2012/10/10 +Date 2012/10/10 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines the EPS Mobility Management procedure call manager, - the main entry point for elementary EMM processing. +Description Defines the EPS Mobility Management procedure call manager, + the main entry point for elementary EMM processing. *****************************************************************************/ #ifndef __EMM_MAIN_H__ @@ -41,7 +41,7 @@ Description Defines the EPS Mobility Management procedure call manager, /****************************************************************************/ #ifdef NAS_UE -void emm_main_initialize(emm_indication_callback_t cb, const char* imei); +void emm_main_initialize(emm_indication_callback_t cb, const char *imei); #endif #ifdef NAS_MME void emm_main_initialize(void); @@ -51,24 +51,24 @@ void emm_main_cleanup(void); #ifdef NAS_UE /* User's getter of UE's identity */ -const imsi_t* emm_main_get_imsi(void); +const imsi_t *emm_main_get_imsi(void); /* User's getter of the subscriber dialing number */ -const msisdn_t* emm_main_get_msisdn(void); +const msisdn_t *emm_main_get_msisdn(void); /* User's getter/setter for network selection */ int emm_main_set_plmn_selection_mode(int mode, int format, - const network_plmn_t* plmn, int rat); + const network_plmn_t *plmn, int rat); int emm_main_get_plmn_selection_mode(void); -int emm_main_get_plmn_list(const char** plist); -const char* emm_main_get_selected_plmn(network_plmn_t* plmn, int format); +int emm_main_get_plmn_list(const char **plist); +const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format); /* User's getter for network registration */ Stat_t emm_main_get_plmn_status(void); tac_t emm_main_get_plmn_tac(void); ci_t emm_main_get_plmn_ci(void); AcT_t emm_main_get_plmn_rat(void); -const char* emm_main_get_registered_plmn(network_plmn_t* plmn, int format); +const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format); /* User's getter for network attachment */ int emm_main_is_attached(void); diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_proc.h b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_proc.h index a3d7ccf65da68df739989b404c308f7c555749c2..9f24fa67ad74536820acab34e7fad199359ad3f3 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_proc.h +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_proc.h @@ -1,21 +1,21 @@ /***************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 2012 Eurecom + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom -Source emm_proc.h +Source emm_proc.h -Version 0.1 +Version 0.1 -Date 2012/10/16 +Date 2012/10/16 -Product NAS stack +Product NAS stack -Subsystem EPS Mobility Management +Subsystem EPS Mobility Management -Author Frederic Maurel +Author Frederic Maurel -Description Defines the EPS Mobility Management procedures executed at - the EMM Service Access Points. +Description Defines the EPS Mobility Management procedures executed at + the EMM Service Access Points. *****************************************************************************/ #ifndef __EMM_PROC_H__ @@ -78,7 +78,7 @@ typedef enum { /* *--------------------------------------------------------------------------- - * EMM status procedure + * EMM status procedure *--------------------------------------------------------------------------- */ int emm_proc_status_ind(unsigned int ueid, int emm_cause); @@ -86,14 +86,14 @@ int emm_proc_status(unsigned int ueid, int emm_cause); /* *--------------------------------------------------------------------------- - * Lower layer procedure + * Lower layer procedure *--------------------------------------------------------------------------- */ #ifdef NAS_UE int emm_proc_lowerlayer_initialize(lowerlayer_success_callback_t success, - lowerlayer_failure_callback_t failure, - lowerlayer_release_callback_t release, - void* args); + lowerlayer_failure_callback_t failure, + lowerlayer_release_callback_t release, + void *args); int emm_proc_lowerlayer_success(void); int emm_proc_lowerlayer_failure(int is_initial); int emm_proc_lowerlayer_release(void); @@ -101,7 +101,7 @@ int emm_proc_lowerlayer_release(void); /* *--------------------------------------------------------------------------- - * UE's Idle mode procedure + * UE's Idle mode procedure *--------------------------------------------------------------------------- */ #ifdef NAS_UE @@ -112,17 +112,19 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat); /* * -------------------------------------------------------------------------- - * Attach procedure + * Attach procedure * -------------------------------------------------------------------------- */ #ifdef NAS_UE int emm_proc_attach(emm_proc_attach_type_t type); -int emm_proc_attach_request(void* args); -int emm_proc_attach_accept(long T3412, long T3402, long T3423, int n_tais, tai_t* tai, GUTI_t* guti, int n_eplmns, plmn_t* eplmn, const OctetString* esm_msg); -int emm_proc_attach_reject(int emm_cause, const OctetString* esm_msg); -int emm_proc_attach_complete(void* args); -int emm_proc_attach_failure(int is_initial, void* args); -int emm_proc_attach_release(void* args); +int emm_proc_attach_request(void *args); +int emm_proc_attach_accept(long T3412, long T3402, long T3423, int n_tais, + tai_t *tai, GUTI_t *guti, int n_eplmns, plmn_t *eplmn, + const OctetString *esm_msg); +int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg); +int emm_proc_attach_complete(void *args); +int emm_proc_attach_failure(int is_initial, void *args); +int emm_proc_attach_release(void *args); int emm_proc_attach_restart(void); int emm_proc_attach_set_emergency(void); @@ -130,32 +132,36 @@ int emm_proc_attach_set_detach(void); #endif #ifdef NAS_MME -int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, int native_ksi, int ksi, int native_guti, GUTI_t* guti, imsi_t* imsi, imei_t* imei, tai_t* tai, int eea, int eia, const OctetString* esm_msg); +int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, + int native_ksi, int ksi, int native_guti, GUTI_t *guti, imsi_t *imsi, + imei_t *imei, tai_t *tai, int eea, int eia, const OctetString *esm_msg); int emm_proc_attach_reject(unsigned int ueid, int emm_cause); -int emm_proc_attach_complete(unsigned int ueid, const OctetString* esm_msg); +int emm_proc_attach_complete(unsigned int ueid, const OctetString *esm_msg); #endif /* * -------------------------------------------------------------------------- - * Detach procedure + * Detach procedure * -------------------------------------------------------------------------- */ #ifdef NAS_UE int emm_proc_detach(emm_proc_detach_type_t type, int switch_off); -int emm_proc_detach_request(void* args); +int emm_proc_detach_request(void *args); int emm_proc_detach_accept(void); -int emm_proc_detach_failure(int is_initial, void* args); -int emm_proc_detach_release(void* args); +int emm_proc_detach_failure(int is_initial, void *args); +int emm_proc_detach_release(void *args); #endif #ifdef NAS_MME int emm_proc_detach(unsigned int ueid, emm_proc_detach_type_t type); -int emm_proc_detach_request(unsigned int ueid, emm_proc_detach_type_t type, int switch_off, int native_ksi, int ksi, GUTI_t* guti, imsi_t* imsi, imei_t* imei); +int emm_proc_detach_request(unsigned int ueid, emm_proc_detach_type_t type, + int switch_off, int native_ksi, int ksi, GUTI_t *guti, imsi_t *imsi, + imei_t *imei); #endif /* * -------------------------------------------------------------------------- - * Identification procedure + * Identification procedure * -------------------------------------------------------------------------- */ #ifdef NAS_UE @@ -169,50 +175,54 @@ int emm_proc_identification(unsigned int ueid, emm_common_success_callback_t success, emm_common_reject_callback_t reject, emm_common_failure_callback_t failure); -int emm_proc_identification_complete(unsigned int ueid, const imsi_t* imsi, const imei_t* imei, UInt32_t* tmsi); +int emm_proc_identification_complete(unsigned int ueid, const imsi_t *imsi, + const imei_t *imei, UInt32_t *tmsi); #endif /* * -------------------------------------------------------------------------- - * Authentication procedure + * Authentication procedure * -------------------------------------------------------------------------- */ #ifdef NAS_UE -int emm_proc_authentication_request(int native_ksi, int ksi, const OctetString* rand, const OctetString* autn); +int emm_proc_authentication_request(int native_ksi, int ksi, + const OctetString *rand, const OctetString *autn); int emm_proc_authentication_reject(void); int emm_proc_authentication_delete(void); #endif #ifdef NAS_MME int emm_proc_authentication(unsigned int ueid, int ksi, - const OctetString* rand, const OctetString* autn, - emm_common_success_callback_t success, - emm_common_reject_callback_t reject, - emm_common_failure_callback_t failure); -int emm_proc_authentication_complete(unsigned int ueid, int emm_cause, const OctetString* res); + const OctetString *rand, const OctetString *autn, + emm_common_success_callback_t success, + emm_common_reject_callback_t reject, + emm_common_failure_callback_t failure); +int emm_proc_authentication_complete(unsigned int ueid, int emm_cause, + const OctetString *res); #endif /* * -------------------------------------------------------------------------- - * Security mode control procedure + * Security mode control procedure * -------------------------------------------------------------------------- */ #ifdef NAS_UE -int emm_proc_security_mode_command(int native_ksi, int ksi, int seea, int seia, int reea, int reia); +int emm_proc_security_mode_command(int native_ksi, int ksi, int seea, int seia, + int reea, int reia); #endif #ifdef NAS_MME int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia, - emm_common_success_callback_t success, - emm_common_reject_callback_t reject, - emm_common_failure_callback_t failure); + emm_common_success_callback_t success, + emm_common_reject_callback_t reject, + emm_common_failure_callback_t failure); int emm_proc_security_mode_complete(unsigned int ueid); int emm_proc_security_mode_reject(unsigned int ueid); #endif /* *--------------------------------------------------------------------------- - * Network indication handlers + * Network indication handlers *--------------------------------------------------------------------------- */ #ifdef NAS_UE