diff --git a/openair3/NAS/UE/EMM/Attach.c b/openair3/NAS/UE/EMM/Attach.c
index 7084c69f9202dc0df730a1c034843b9d3f412b61..3204e5f2da5a5ccf78475e8e1db69e65aac589df 100644
--- a/openair3/NAS/UE/EMM/Attach.c
+++ b/openair3/NAS/UE/EMM/Attach.c
@@ -133,7 +133,7 @@ static struct {
  **      INITIATED.                                                **
  **                                                                        **
  ** Inputs:  type:      Type of the requested attach               **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
@@ -154,7 +154,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type)
 
   /* Update the emergency bearer service indicator */
   if (type == EMM_ATTACH_TYPE_EMERGENCY) {
-    _emm_data.is_emergency = TRUE;
+    user->emm_data->is_emergency = TRUE;
   }
 
   /* Setup initial NAS information message to transfer */
@@ -163,7 +163,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type)
   emm_as->type = type;
 
   /* Set the RRC connection establishment cause */
-  if (_emm_data.is_emergency) {
+  if (user->emm_data->is_emergency) {
     emm_as->RRCcause = NET_ESTABLISH_CAUSE_EMERGENCY;
     emm_as->RRCtype = NET_ESTABLISH_TYPE_EMERGENCY_CALLS;
   } else {
@@ -172,7 +172,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type)
   }
 
   /* Set the PLMN identifier of the selected PLMN */
-  emm_as->plmnID = &_emm_data.splmn;
+  emm_as->plmnID = &user->emm_data->splmn;
   /*
    * Process the EPS mobile identity
    */
@@ -182,55 +182,55 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type)
   emm_as->UEid.imei = NULL;
 
   /* Check whether the UE is configured for "AttachWithIMSI" */
-  if (_emm_data.AttachWithImsi) {
+  if (user->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) ) {
+    if ( (!user->emm_data->is_rplmn) && (!user->emm_data->is_eplmn) ) {
       LOG_TRACE(INFO, "EMM-PROC  - Initiate EPS attach with IMSI");
       /* Include the IMSI */
-      emm_as->UEid.imsi = _emm_data.imsi;
+      emm_as->UEid.imsi = user->emm_data->imsi;
     } else {
       LOG_TRACE(INFO,
                 "EMM-PROC  - Initiate EPS attach with NO IMSI, is registered PLMN %d, is equivalent PLMN %d",
-                _emm_data.is_rplmn,
-                _emm_data.is_eplmn);
+                user->emm_data->is_rplmn,
+                user->emm_data->is_eplmn);
     }
-  } else if (_emm_data.guti) {
+  } else if (user->emm_data->guti) {
     LOG_TRACE(INFO, "EMM-PROC  - Initiate EPS attach with 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) {
+    emm_as->UEid.guti = user->emm_data->guti;
+    emm_as->UEid.tai = user->emm_data->tai;
+  } else if (!user->emm_data->is_emergency) {
     LOG_TRACE(INFO, "EMM-PROC  - Initiate EPS attach with IMSI cause is no emergency and no GUTI");
     /* Include the IMSI if no valid GUTI is available */
-    emm_as->UEid.imsi = _emm_data.imsi;
+    emm_as->UEid.imsi = user->emm_data->imsi;
   } else {
     /* The UE is attaching for emergency bearer services and
      * does not hold a valid GUTI */
-    if (_emm_data.imsi) {
+    if (user->emm_data->imsi) {
       /* Include the IMSI if valid (USIM is present) */
       LOG_TRACE(INFO, "EMM-PROC  - Initiate EPS attach with IMSI cause is emergency and no GUTI");
-      emm_as->UEid.imsi = _emm_data.imsi;
+      emm_as->UEid.imsi = user->emm_data->imsi;
     } else {
       LOG_TRACE(INFO, "EMM-PROC  - Initiate EPS attach with IMSI cause is emergency and no GUTI and no IMSI");
       /* Include the IMEI if the IMSI is not valid */
-      emm_as->UEid.imei = _emm_data.imei;
+      emm_as->UEid.imei = user->emm_data->imei;
     }
   }
 
   /* Setup EPS NAS security data */
-  emm_as_set_security_data(&emm_as->sctx, _emm_data.security, FALSE, FALSE);
+  emm_as_set_security_data(&emm_as->sctx, user->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;
+  if (user->emm_data->security) {
+    if (user->emm_data->security->type != EMM_KSI_NOT_AVAILABLE) {
+      emm_as->ksi = user->emm_data->security->eksi;
     }
 
-    LOG_TRACE(INFO, "EMM-PROC  - eps_encryption 0x%X", _emm_data.security->capability.eps_encryption);
-    LOG_TRACE(INFO, "EMM-PROC  - eps_integrity  0x%X", _emm_data.security->capability.eps_integrity);
-    emm_as->encryption = _emm_data.security->capability.eps_encryption;
-    emm_as->integrity = _emm_data.security->capability.eps_integrity;
+    LOG_TRACE(INFO, "EMM-PROC  - eps_encryption 0x%X", user->emm_data->security->capability.eps_encryption);
+    LOG_TRACE(INFO, "EMM-PROC  - eps_integrity  0x%X", user->emm_data->security->capability.eps_integrity);
+    emm_as->encryption = user->emm_data->security->capability.eps_encryption;
+    emm_as->integrity = user->emm_data->security->capability.eps_integrity;
   }
 
   /*
@@ -244,7 +244,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type)
   /* TODO: PDN type should be set according to the IP capability of the UE */
   esm_sap.data.pdn_connect.pdn_type = NET_PDN_TYPE_IPV4;
   esm_sap.data.pdn_connect.apn = NULL;
-  esm_sap.data.pdn_connect.is_emergency = _emm_data.is_emergency;
+  esm_sap.data.pdn_connect.is_emergency = user->emm_data->is_emergency;
   rc = esm_sap_send(user, &esm_sap);
 
   if (rc != RETURNerror) {
@@ -342,7 +342,7 @@ int emm_proc_attach_request(void *args)
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **      Others:    _emm_data, T3412, T3402, T3423             **
+ **      Others:    user->emm_data-> T3412, T3402, T3423             **
  **                                                                        **
  ***************************************************************************/
 int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423,
@@ -365,10 +365,10 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423,
   T3410.id = nas_timer_stop(T3410.id);
 
   /* Delete old TAI list and store the received TAI list */
-  _emm_data.ltai.n_tais = n_tais;
+  user->emm_data->ltai.n_tais = n_tais;
 
   for (i = 0; (i < n_tais) && (i < EMM_DATA_TAI_MAX); i++) {
-    _emm_data.ltai.tai[i] = tai[i];
+    user->emm_data->ltai.tai[i] = tai[i];
   }
 
   /* Update periodic tracking area update timer value */
@@ -386,22 +386,22 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423,
 
   /* Delete old GUTI and store the new assigned GUTI if provided */
   if (guti) {
-    *_emm_data.guti = *guti;
+    *user->emm_data->guti = *guti;
   }
 
   /* Update the stored list of equivalent PLMNs */
-  _emm_data.nvdata.eplmn.n_plmns = 0;
+  user->emm_data->nvdata.eplmn.n_plmns = 0;
 
   if (n_eplmns > 0) {
     for (i = 0; (i < n_eplmns) && (i < EMM_DATA_EPLMN_MAX); i++) {
       int is_forbidden = FALSE;
 
-      if (!_emm_data.is_emergency) {
+      if (!user->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 (j = 0; j < _emm_data.fplmn.n_plmns; j++) {
-          if (PLMNS_ARE_EQUAL(eplmn[i], _emm_data.fplmn.plmn[j])) {
+        for (j = 0; j < user->emm_data->fplmn.n_plmns; j++) {
+          if (PLMNS_ARE_EQUAL(eplmn[i], user->emm_data->fplmn.plmn[j])) {
             is_forbidden = TRUE;
             break;
           }
@@ -409,15 +409,15 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423,
       }
 
       if ( !is_forbidden ) {
-        _emm_data.nvdata.eplmn.plmn[_emm_data.nvdata.eplmn.n_plmns++] =
+        user->emm_data->nvdata.eplmn.plmn[user->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;
+    if (user->emm_data->nvdata.eplmn.n_plmns < EMM_DATA_EPLMN_MAX) {
+      user->emm_data->nvdata.eplmn.plmn[user->emm_data->nvdata.eplmn.n_plmns++] =
+        user->emm_data->splmn;
     }
   }
 
@@ -448,11 +448,11 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423,
      * 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.guti = user->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);
+                             user->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 */
@@ -497,7 +497,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423,
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **      Others:    _emm_data, _emm_attach_data, T3410         **
+ **      Others:    user->emm_data-> _emm_attach_data, T3410         **
  **                                                                        **
  ***************************************************************************/
 int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *esm_msg_pP)
@@ -528,15 +528,15 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e
   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;
+    user->emm_data->status = EU3_ROAMING_NOT_ALLOWED;
     /* Delete the GUTI */
-    _emm_data.guti = NULL;
+    user->emm_data->guti = NULL;
     /* Delete the last visited registered TAI */
-    _emm_data.tai = NULL;
+    user->emm_data->tai = NULL;
 
     /* Delete the eKSI */
-    if (_emm_data.security) {
-      _emm_data.security->type = EMM_KSI_NOT_AVAILABLE;
+    if (user->emm_data->security) {
+      user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE;
     }
 
     break;
@@ -552,16 +552,16 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e
   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;
+    user->emm_data->usim_is_valid = FALSE;
     /* Delete the list of equivalent PLMNs */
-    _emm_data.nvdata.eplmn.n_plmns = 0;
+    user->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;
+    user->emm_data->nvdata.eplmn.n_plmns = 0;
     /* Reset the attach attempt counter */
     _emm_attach_data.attempt_count = 0;
     break;
@@ -576,7 +576,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e
   case EMM_CAUSE_ESM_FAILURE:
 
     /* 3GPP TS 24.301, section 5.5.1.2.6, case d */
-    if (_emm_data.NAS_SignallingPriority != 1) {
+    if (user->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;
@@ -603,25 +603,25 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e
   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;
+    user->emm_data->fplmn.plmn[user->emm_data->fplmn.n_plmns++] = user->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;
+    user->emm_data->ftai.tai[user->emm_data->ftai.n_tais++] = *user->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;
+    user->emm_data->ftai_roaming.tai[user->emm_data->ftai_roaming.n_tais++] = *user->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;
+    user->emm_data->fplmn_gprs.plmn[user->emm_data->fplmn_gprs.n_plmns++] = user->emm_data->splmn;
     break;
 
   default :
@@ -662,7 +662,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e
     break;
 
   case EMM_CAUSE_IMEI_NOT_ACCEPTED:
-    if (_emm_data.is_emergency) {
+    if (user->emm_data->is_emergency) {
       /*
        * Notify EMM that the UE failed to register to the network
        * for emergency bearer services because "IMEI not accepted"
@@ -714,7 +714,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **      Others:    _emm_data, _emm_attach_data                **
+ **      Others:    user->emm_data-> _emm_attach_data                **
  **                                                                        **
  ***************************************************************************/
 int emm_proc_attach_complete(void *args)
@@ -736,8 +736,8 @@ int emm_proc_attach_complete(void *args)
   /* TODO: Reset the tracking area updating attempt counter */
 
   /* Set the EPS update status to EU1 UPDATED */
-  _emm_data.status = EU1_UPDATED;
-  _emm_data.is_attached = TRUE;
+  user->emm_data->status = EU1_UPDATED;
+  user->emm_data->is_attached = TRUE;
 
   /*
    * Notify EMM that network attach complete message has been delivered
@@ -897,7 +897,7 @@ int emm_proc_attach_restart(nas_user_t *user)
    * Notify EMM that the attach procedure has to be restarted
    */
   emm_sap.primitive = EMMREG_ATTACH_INIT;
-  emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency;
+  emm_sap.u.emm_reg.u.attach.is_emergency = user->emm_data->is_emergency;
   rc = emm_sap_send(user, &emm_sap);
 
   LOG_FUNC_RETURN(rc);
@@ -914,17 +914,17 @@ int emm_proc_attach_restart(nas_user_t *user)
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ***************************************************************************/
-int emm_proc_attach_set_emergency(void)
+int emm_proc_attach_set_emergency(emm_data_t *emm_data)
 {
   LOG_FUNC_IN;
 
   LOG_TRACE(WARNING, "EMM-PROC  - UE is now attached to the network for "
             "emergency bearer services only");
 
-  _emm_data.is_emergency = TRUE;
+  emm_data->is_emergency = TRUE;
 
   LOG_FUNC_RETURN(RETURNok);
 }
@@ -941,7 +941,7 @@ int emm_proc_attach_set_emergency(void)
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ***************************************************************************/
 int emm_proc_attach_set_detach(void *nas_user)
@@ -955,7 +955,7 @@ int emm_proc_attach_set_detach(void *nas_user)
             "EMM-PROC  - UE is now locally detached from the network");
 
   /* Reset the network attachment indicator */
-  _emm_data.is_attached = FALSE;
+  user->emm_data->is_attached = FALSE;
   /*
    * Notify that the UE is locally detached from the network
    */
@@ -1016,7 +1016,7 @@ void *_emm_attach_t3410_handler(void *args)
 
   if (rc != RETURNerror) {
     /* Locally release the NAS signalling connection */
-    _emm_data.ecm_status = ECM_IDLE;
+    user->emm_data->ecm_status = ECM_IDLE;
   }
 
   LOG_FUNC_RETURN(NULL);
@@ -1056,7 +1056,7 @@ static void *_emm_attach_t3411_handler(void *args)
    * restarted
    */
   emm_sap.primitive = EMMREG_ATTACH_INIT;
-  emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency;
+  emm_sap.u.emm_reg.u.attach.is_emergency = user->emm_data->is_emergency;
 
   (void) emm_sap_send(user, &emm_sap);
 
@@ -1103,7 +1103,7 @@ static void *_emm_attach_t3402_handler(void *args)
    * restarted
    */
   emm_sap.primitive = EMMREG_ATTACH_INIT;
-  emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency;
+  emm_sap.u.emm_reg.u.attach.is_emergency = user->emm_data->is_emergency;
 
   (void) emm_sap_send(user, &emm_sap);
 
@@ -1133,7 +1133,7 @@ static void *_emm_attach_t3402_handler(void *args)
  **                                                                        **
  ** Outputs:     emm_sap:   EMM service access point                   **
  **      Return:    None                                       **
- **      Others:    _emm_data, _emm_attach_data, T3402, T3410, **
+ **      Others:    user->emm_data-> _emm_attach_data, T3402, T3410, **
  **             T3411                                      **
  **                                                                        **
  ***************************************************************************/
@@ -1165,21 +1165,21 @@ static void _emm_attach_abnormal_cases_bcd(nas_user_t *user, emm_sap_t *emm_sap)
     emm_sap->primitive = EMMREG_ATTACH_FAILED;
   } else {
     /* Delete the GUTI */
-    _emm_data.guti = NULL;
+    user->emm_data->guti = NULL;
     /* Delete the TAI list */
-    _emm_data.ltai.n_tais = 0;
+    user->emm_data->ltai.n_tais = 0;
     /* Delete the last visited registered TAI */
-    _emm_data.tai = NULL;
+    user->emm_data->tai = NULL;
     /* Delete the list of equivalent PLMNs */
-    _emm_data.nvdata.eplmn.n_plmns = 0;
+    user->emm_data->nvdata.eplmn.n_plmns = 0;
 
     /* Delete the eKSI */
-    if (_emm_data.security) {
-      _emm_data.security->type = EMM_KSI_NOT_AVAILABLE;
+    if (user->emm_data->security) {
+      user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE;
     }
 
     /* Set the EPS update status to EU2 NOT UPDATED */
-    _emm_data.status = EU2_NOT_UPDATED;
+    user->emm_data->status = EU2_NOT_UPDATED;
 
     /* Start T3402 timer */
     T3402.id = nas_timer_start(T3402.sec, _emm_attach_t3402_handler, user);
diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c
index 7b5672c3bff2e1dbaa13c1fce16c030ce51f59e7..daa7f5a1f7592ab1d62665c16a141822ebedce9a 100644
--- a/openair3/NAS/UE/EMM/Authentication.c
+++ b/openair3/NAS/UE/EMM/Authentication.c
@@ -163,11 +163,11 @@ static int _authentication_kasme(const OctetString *autn,
  **      ksi:       The NAS ket sey identifier                 **
  **      rand:      Authentication parameter RAND              **
  **      autn:      Authentication parameter AUTN              **
- **      Others:    _emm_data, _authentication_data            **
+ **      Others:    user->emm_data-> _authentication_data            **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **      Others:    _emm_data, _authentication_data, T3416,    **
+ **      Others:    user->emm_data-> _authentication_data, T3416,    **
  **             T3418, T3420                               **
  **                                                                        **
  ***************************************************************************/
@@ -185,7 +185,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi,
    * The UE shall proceed with an EPS authentication challenge only if a
    * USIM is present
    */
-  if (!_emm_data.usim_is_valid) {
+  if (!user->emm_data->usim_is_valid) {
     LOG_TRACE(WARNING, "EMM-PROC  - USIM is not present or not valid");
     LOG_FUNC_RETURN (RETURNerror);
   }
@@ -327,14 +327,14 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi,
    */
   emm_sap_t emm_sap;
   emm_sap.primitive = EMMAS_SECURITY_RES;
-  emm_sap.u.emm_as.u.security.guti = _emm_data.guti;
+  emm_sap.u.emm_as.u.security.guti = user->emm_data->guti;
   emm_sap.u.emm_as.u.security.ueid = 0;
   emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH;
   emm_sap.u.emm_as.u.security.emm_cause = EMM_CAUSE_SUCCESS;
   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);
+                           user->emm_data->security, FALSE, TRUE);
   rc = emm_sap_send(user, &emm_sap);
 
   if (rc != RETURNerror) {
@@ -344,29 +344,29 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi,
     _authentication_data.sync_count = 0;
 
     /* Create non-current EPS security context */
-    if (_emm_data.non_current == NULL) {
-      _emm_data.non_current =
+    if (user->emm_data->non_current == NULL) {
+      user->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));
+    if (user->emm_data->non_current) {
+      memset(user->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;
+        user->emm_data->non_current->type = EMM_KSI_NATIVE;
       } else {
-        _emm_data.non_current->type = EMM_KSI_MAPPED;
+        user->emm_data->non_current->type = EMM_KSI_MAPPED;
       }
 
       /* Set the EPS key set identifier */
-      _emm_data.non_current->eksi = ksi;
+      user->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  = malloc(32);
-      _authentication_kasme(autn, &ck, &ik, &_emm_data.splmn,
-                            &_emm_data.non_current->kasme);
+      user->emm_data->non_current->kasme.length = AUTH_KASME_SIZE;
+      user->emm_data->non_current->kasme.value  = malloc(32);
+      _authentication_kasme(autn, &ck, &ik, &user->emm_data->splmn,
+                            &user->emm_data->non_current->kasme);
       /* NAS integrity and cyphering keys are not yet available */
     }
   }
@@ -392,7 +392,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi,
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **      Others:    _emm_data, _authentication_data, T3410,    **
+ **      Others:    user->emm_data-> _authentication_data, T3410,    **
  **             T3417, T3430                               **
  **                                                                        **
  ***************************************************************************/
@@ -409,21 +409,21 @@ int emm_proc_authentication_reject(nas_user_t *user)
   (void) emm_proc_authentication_delete();
 
   /* Set the EPS update status to EU3 ROAMING NOT ALLOWED */
-  _emm_data.status = EU3_ROAMING_NOT_ALLOWED;
+  user->emm_data->status = EU3_ROAMING_NOT_ALLOWED;
   /* Delete the stored GUTI */
-  _emm_data.guti = NULL;
+  user->emm_data->guti = NULL;
   /* Delete the TAI list */
-  _emm_data.ltai.n_tais = 0;
+  user->emm_data->ltai.n_tais = 0;
   /* Delete the last visited registered TAI */
-  _emm_data.tai = NULL;
+  user->emm_data->tai = NULL;
 
   /* Delete the eKSI */
-  if (_emm_data.security) {
-    _emm_data.security->type = EMM_KSI_NOT_AVAILABLE;
+  if (user->emm_data->security) {
+    user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE;
   }
 
   /* Consider the USIM invalid */
-  _emm_data.usim_is_valid = FALSE;
+  user->emm_data->usim_is_valid = FALSE;
 
   /* Stop timer T3410 */
   if (T3410.id != NAS_TIMER_INACTIVE_ID) {
@@ -664,14 +664,14 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause,
    */
   emm_sap_t emm_sap;
   emm_sap.primitive = EMMAS_SECURITY_RES;
-  emm_sap.u.emm_as.u.security.guti = _emm_data.guti;
+  emm_sap.u.emm_as.u.security.guti = user->emm_data->guti;
   emm_sap.u.emm_as.u.security.ueid = 0;
   emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH;
   emm_sap.u.emm_as.u.security.emm_cause = 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);
+                           user->emm_data->security, FALSE, TRUE);
   rc = emm_sap_send(user, &emm_sap);
 
   if (rc != RETURNerror) {
@@ -787,7 +787,7 @@ static int _authentication_abnormal_case_f(nas_user_t *user)
    */
   emm_sap_t emm_sap;
   emm_sap.primitive = EMMAS_RELEASE_REQ;
-  emm_sap.u.emm_as.u.release.guti = _emm_data.guti;
+  emm_sap.u.emm_as.u.release.guti = user->emm_data->guti;
   emm_sap.u.emm_as.u.release.cause = EMM_AS_CAUSE_AUTHENTICATION;
   rc = emm_sap_send(user, &emm_sap);
 
diff --git a/openair3/NAS/UE/EMM/Detach.c b/openair3/NAS/UE/EMM/Detach.c
index 7ea4220cae407187bd929bbb285dec4c0e378d71..480e24448a8bbad437066f7d4be21e88a8020f82 100644
--- a/openair3/NAS/UE/EMM/Detach.c
+++ b/openair3/NAS/UE/EMM/Detach.c
@@ -124,7 +124,7 @@ static struct {
  ** 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                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
@@ -167,10 +167,10 @@ int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_of
   /* Set the switch-off indicator */
   emm_as->switch_off = switch_off;
   /* Set the EPS mobile identity */
-  emm_as->guti = _emm_data.guti;
+  emm_as->guti = user->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);
+  emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, TRUE);
 
   /*
    * Notify EMM-AS SAP that Detach Request message has to
@@ -413,10 +413,10 @@ void *_emm_detach_t3421_handler(void *args)
     /* 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->guti = user->emm_data->guti;
     emm_as->ueid = 0;
     /* Setup EPS NAS security data */
-    emm_as_set_security_data(&emm_as->sctx, _emm_data.security,
+    emm_as_set_security_data(&emm_as->sctx, user->emm_data->security,
                              FALSE, TRUE);
 
     /*
diff --git a/openair3/NAS/UE/EMM/EmmStatusHdl.c b/openair3/NAS/UE/EMM/EmmStatusHdl.c
index c0c1fc24de6d83993e89efbbbd3790d49351d93a..320ca985ffe58f43a137aa74867a275ce8a1420b 100644
--- a/openair3/NAS/UE/EMM/EmmStatusHdl.c
+++ b/openair3/NAS/UE/EMM/EmmStatusHdl.c
@@ -134,8 +134,8 @@ int emm_proc_status(nas_user_t *user, unsigned int ueid, int emm_cause)
   emm_sap.u.emm_as.u.status.emm_cause = emm_cause;
   emm_sap.u.emm_as.u.status.ueid = ueid;
 
-  emm_sap.u.emm_as.u.status.guti = _emm_data.guti;
-  sctx = _emm_data.security;
+  emm_sap.u.emm_as.u.status.guti = user->emm_data->guti;
+  sctx = user->emm_data->security;
   /* Setup EPS NAS security data */
   emm_as_set_security_data(&emm_sap.u.emm_as.u.status.sctx, sctx,
                            FALSE, TRUE);
diff --git a/openair3/NAS/UE/EMM/Identification.c b/openair3/NAS/UE/EMM/Identification.c
index ce64e658505eae5b314cb9fe9b00d5bbf8078084..53bc008cab162bc3a9f12d5cd04ac79048a76ab9 100644
--- a/openair3/NAS/UE/EMM/Identification.c
+++ b/openair3/NAS/UE/EMM/Identification.c
@@ -130,8 +130,8 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t
     imsi_t modified_imsi;
 
     /* International Mobile Subscriber Identity is requested */
-    if (_emm_data.imsi) {
-      memcpy (&modified_imsi, _emm_data.imsi, sizeof (modified_imsi));
+    if (user->emm_data->imsi) {
+      memcpy (&modified_imsi, user->emm_data->imsi, sizeof (modified_imsi));
 
       /* LW: Eventually replace the 0xF value set in MNC digit 3 by a 0 to avoid IMSI to be truncated before reaching HSS */
       if (modified_imsi.u.num.digit6 == 0xF) {
@@ -167,9 +167,9 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t
   case EMM_IDENT_TYPE_IMEI:
 
     /* International Mobile Equipment Identity is requested */
-    if (_emm_data.imei) {
+    if (user->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;
+      emm_sap.u.emm_as.u.security.imei = user->emm_data->imei;
     }
 
     break;
@@ -177,9 +177,9 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t
   case EMM_IDENT_TYPE_TMSI:
 
     /* Temporary Mobile Subscriber Identity is requested */
-    if (_emm_data.guti) {
+    if (user->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;
+      emm_sap.u.emm_as.u.security.tmsi = user->emm_data->guti->m_tmsi;
     }
 
     break;
@@ -194,12 +194,12 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t
    * to the MME
    */
   emm_sap.primitive = EMMAS_SECURITY_RES;
-  emm_sap.u.emm_as.u.security.guti = _emm_data.guti;
+  emm_sap.u.emm_as.u.security.guti = user->emm_data->guti;
   emm_sap.u.emm_as.u.security.ueid = 0;
   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);
+                           user->emm_data->security, FALSE, TRUE);
   rc = emm_sap_send(user, &emm_sap);
 
   LOG_FUNC_RETURN (rc);
diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c
index f7e3274614a9eb5b6624b7bd816b01e658f8f14d..8570a5878949190a6209d9cfeaa5ce9e293c274c 100644
--- a/openair3/NAS/UE/EMM/IdleMode.c
+++ b/openair3/NAS/UE/EMM/IdleMode.c
@@ -269,10 +269,9 @@ int IdleMode_get_splmn_index(void)
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    The size of the list in bytes              **
- **          Others:    _emm_data.plist                            **
  **                                                                        **
  ***************************************************************************/
-int IdleMode_update_plmn_list(int i)
+int IdleMode_update_plmn_list(emm_data_t *emm_data, int i)
 {
   int offset = 0;
   int n = 1;
@@ -281,22 +280,22 @@ int IdleMode_update_plmn_list(int i)
     struct plmn_param_t *plmn = &(_emm_plmn_list.param[i++]);
 
     if (n++ > 1) {
-      offset += snprintf(_emm_data.plist.buffer + offset,
+      offset += snprintf(emm_data->plist.buffer + offset,
                          EMM_DATA_BUFFER_SIZE - offset, ",");
     }
 
-    offset += snprintf(_emm_data.plist.buffer + 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,
+      offset += snprintf(emm_data->plist.buffer + offset,
                          EMM_DATA_BUFFER_SIZE - offset, ",%d",
                          plmn->rat);
     }
 
-    offset += snprintf(_emm_data.plist.buffer + offset,
+    offset += snprintf(emm_data->plist.buffer + offset,
                        EMM_DATA_BUFFER_SIZE - offset, ")");
   }
 
@@ -503,7 +502,7 @@ int IdleMode_get_plmn_id_index(const char *plmn)
  **      to PLMN selection procedure.                              **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
@@ -518,21 +517,21 @@ int emm_proc_initialize(nas_user_t *user)
   int rc;
   int i;
 
-  if (!_emm_data.usim_is_valid) {
+  if (!user->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 (i=0; i < _emm_data.nvdata.eplmn.n_plmns; i++) {
+    if (user->emm_data->nvdata.eplmn.n_plmns > 0) {
+      for (i=0; i < user->emm_data->nvdata.eplmn.n_plmns; i++) {
         _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] =
-          &_emm_data.nvdata.eplmn.plmn[i];
+          &user->emm_data->nvdata.eplmn.plmn[i];
       }
-    } else if ( PLMN_IS_VALID(_emm_data.nvdata.rplmn) ) {
+    } else if ( PLMN_IS_VALID(user->emm_data->nvdata.rplmn) ) {
       _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] =
-        &_emm_data.nvdata.rplmn;
+        &user->emm_data->nvdata.rplmn;
     }
 
     /* Update the index of the HPLMN or EHPLM of highest priority.
@@ -544,25 +543,25 @@ int emm_proc_initialize(nas_user_t *user)
 
     /* 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) {
+    if (user->emm_data->ehplmn.n_plmns > 0) {
       _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] =
-        &_emm_data.ehplmn.plmn[0];
+        &user->emm_data->ehplmn.plmn[0];
     } else {
-      _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = &_emm_data.hplmn;
+      _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = &user->emm_data->hplmn;
     }
 
     /* Each PLMN/access technology combination in the "User
      * Controlled PLMN Selector with Access Technology" */
-    for (i=0; i < _emm_data.plmn.n_plmns; i++) {
+    for (i=0; i < user->emm_data->plmn.n_plmns; i++) {
       _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] =
-        &_emm_data.plmn.plmn[i];
+        &user->emm_data->plmn.plmn[i];
     }
 
     /* Each PLMN/access technology combination in the "Operator
      * Controlled PLMN Selector with Access Technology" */
-    for (i=0; i < _emm_data.oplmn.n_plmns; i++) {
+    for (i=0; i < user->emm_data->oplmn.n_plmns; i++) {
       _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] =
-        &_emm_data.oplmn.plmn[i];
+        &user->emm_data->oplmn.plmn[i];
     }
 
     /* Other PLMN/access technology combinations with received
@@ -582,9 +581,9 @@ int emm_proc_initialize(nas_user_t *user)
         plmn->fullname[0] = '\0';
         plmn->shortname[0] = '\0';
       } else {
-        strncpy(plmn->fullname, _emm_data.opnn[id].fullname,
+        strncpy(plmn->fullname, user->emm_data->opnn[id].fullname,
                 NET_FORMAT_LONG_SIZE);
-        strncpy(plmn->shortname, _emm_data.opnn[id].shortname,
+        strncpy(plmn->shortname, user->emm_data->opnn[id].shortname,
                 NET_FORMAT_SHORT_SIZE);
       }
 
@@ -627,7 +626,7 @@ int emm_proc_initialize(nas_user_t *user)
  **      mode.                                                     **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _emm_plmn_list, _emm_data                  **
+ **      Others:    _emm_plmn_list, user->emm_data->                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    None                                       **
@@ -640,7 +639,7 @@ int emm_proc_plmn_selection(nas_user_t *user, int index)
 
   int rc = RETURNok;
 
-  if (_emm_data.plmn_mode != EMM_DATA_PLMN_AUTO) {
+  if (user->emm_data->plmn_mode != EMM_DATA_PLMN_AUTO) {
     /*
      * Manual or manual/automatic mode of operation
      * --------------------------------------------
@@ -649,13 +648,13 @@ int emm_proc_plmn_selection(nas_user_t *user, int index)
       /*
        * Selection of the last registered or equivalent PLMNs failed
        */
-      if (_emm_data.plmn_index < 0) {
+      if (user->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);
+        rc = emm_proc_network_notify(user->emm_data, _emm_plmn_list.hplmn);
 
         if (rc != RETURNok) {
           LOG_TRACE(WARNING, "EMM-IDLE  - Failed to notify "
@@ -665,7 +664,7 @@ int emm_proc_plmn_selection(nas_user_t *user, int index)
         /*
          * Try to register to the PLMN manually selected by the user
          */
-        index = _emm_data.plmn_index;
+        index = user->emm_data->plmn_index;
       }
     }
   }
@@ -714,11 +713,11 @@ int emm_proc_plmn_selection(nas_user_t *user, int index)
  **      ci:        The identifier of the cell                 **
  **      rat:       The radio access technology supported by   **
  **             the cell                                   **
- **      Others:    _emm_plmn_list, _emm_data                  **
+ **      Others:    _emm_plmn_list, user->emm_data->                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    None                                       **
- **      Others:    _emm_plmn_list, _emm_data                  **
+ **      Others:    _emm_plmn_list, user->emm_data->                 **
  **                                                                        **
  ***************************************************************************/
 int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t rat)
@@ -732,15 +731,15 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci,
 
   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" :
+            (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" :
+            (user->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];
+    user->emm_data->splmn = *_emm_plmn_list.plmn[index];
 
     /* Update the selected PLMN's parameters */
     _emm_plmn_list.param[index].tac = tac;
@@ -748,13 +747,13 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t 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);
+    rc = emm_proc_location_notify(user->emm_data, 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) {
+    if (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) {
       /*
        * Automatic mode of operation
        * ---------------------------
@@ -762,17 +761,17 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci,
       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])) {
+      for (i = 0; i < user->emm_data->fplmn.n_plmns; i++) {
+        if (PLMNS_ARE_EQUAL(user->emm_data->splmn, user->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])) {
+        for (i = 0; i < user->emm_data->fplmn_gprs.n_plmns; i++) {
+          if (PLMNS_ARE_EQUAL(user->emm_data->splmn,
+                              user->emm_data->fplmn_gprs.plmn[i])) {
             is_forbidden = TRUE;
             break;
           }
@@ -782,12 +781,12 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci,
       /* Check if the selected PLMN belongs to a forbidden
        * tracking area */
       tai_t tai;
-      tai.plmn = _emm_data.splmn;
+      tai.plmn = user->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])) {
+        for (i = 0; i < user->emm_data->ftai.n_tais; i++) {
+          if (TAIS_ARE_EQUAL(tai, user->emm_data->ftai.tai[i])) {
             is_forbidden = TRUE;
             break;
           }
@@ -795,8 +794,8 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci,
       }
 
       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])) {
+        for (i = 0; i < user->emm_data->ftai_roaming.n_tais; i++) {
+          if (TAIS_ARE_EQUAL(tai, user->emm_data->ftai_roaming.tai[i])) {
             is_forbidden = TRUE;
             break;
           }
@@ -825,10 +824,10 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci,
     }
 
     /* Duplicate the new selected PLMN at the end of the ordered list */
-    _emm_plmn_list.plmn[_emm_plmn_list.n_plmns] = &_emm_data.splmn;
+    _emm_plmn_list.plmn[_emm_plmn_list.n_plmns] = &user->emm_data->splmn;
   }
 
-  else if (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO) {
+  else if (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) {
     /*
      * Automatic mode of operation
      * ---------------------------
@@ -844,7 +843,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci,
     }
   }
 
-  else if (_emm_data.plmn_index < 0) {
+  else if (user->emm_data->plmn_index < 0) {
     /*
      * Manual or manual/automatic mode of operation
      * --------------------------------------------
@@ -855,7 +854,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci,
     select_next_plmn = TRUE;
   }
 
-  else if (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL) {
+  else if (user->emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL) {
     /*
      * Manual mode of operation
      * ------------------------
@@ -871,7 +870,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci,
      * 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;
+    user->emm_data->plmn_mode = EMM_DATA_PLMN_AUTO;
     index = _emm_plmn_list.hplmn;
     select_next_plmn = TRUE;
   }
@@ -938,11 +937,11 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci,
       if (_emm_plmn_list.splmn == _emm_plmn_list.rplmn) {
         /* The selected PLMN is the registered PLMN */
         LOG_TRACE(INFO, "EMM-IDLE  - The selected PLMN is the registered PLMN");
-        _emm_data.is_rplmn = TRUE;
+        user->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 */
         LOG_TRACE(INFO, "EMM-IDLE  - The selected PLMN is in the list of equivalent PLMNs");
-        _emm_data.is_eplmn = TRUE;
+        user->emm_data->is_eplmn = TRUE;
       }
 
       /*
@@ -976,20 +975,20 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci,
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **          Others:    _emm_data                                  **
+ **          Others:    user->emm_data->                                 **
  **                                                                        **
  ***************************************************************************/
-int emm_proc_registration_notify(Stat_t status)
+int emm_proc_registration_notify(emm_data_t *emm_data, Stat_t status)
 {
   LOG_FUNC_IN;
 
   int rc = RETURNok;
 
   /* Update the network registration status */
-  if (_emm_data.stat != status) {
-    _emm_data.stat = status;
+  if (emm_data->stat != status) {
+    emm_data->stat = status;
     /* Notify EMM that data has changed */
-    rc = (*_emm_indication_notify)(1);
+    rc = (*_emm_indication_notify)(emm_data, 1);
   }
 
   LOG_FUNC_RETURN (rc);
@@ -1010,24 +1009,24 @@ int emm_proc_registration_notify(Stat_t status)
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **          Others:    _emm_data                                  **
+ **          Others:    user->emm_data->                                 **
  **                                                                        **
  ***************************************************************************/
-int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat)
+int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat)
 {
   LOG_FUNC_IN;
 
   int rc = RETURNok;
 
   /* 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;
+  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);
+    rc = (*_emm_indication_notify)(emm_data, 0);
   }
 
   LOG_FUNC_RETURN (rc);
@@ -1047,17 +1046,17 @@ int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat)
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **          Others:    _emm_data                                  **
+ **          Others:    user->emm_data->                                 **
  **                                                                        **
  ***************************************************************************/
-int emm_proc_network_notify(int index)
+int emm_proc_network_notify(emm_data_t *emm_data, int index)
 {
   LOG_FUNC_IN;
 
   /* Update the list of operators present in the network */
-  int size = IdleMode_update_plmn_list(index);
+  int size = IdleMode_update_plmn_list(emm_data, index);
   /* Notify EMM that data has changed */
-  int rc = (*_emm_indication_notify)(size);
+  int rc = (*_emm_indication_notify)(emm_data, size);
 
   LOG_FUNC_RETURN (rc);
 }
@@ -1126,7 +1125,7 @@ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn)
  **      tor network name records                                  **
  **                                                                        **
  ** Inputs:  plmn:      The PLMN identifier                        **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    The index of the PLMN if found in the list **
@@ -1139,28 +1138,28 @@ static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn)
 {
   int i;
 
-  for (i = 0; i < _emm_data.n_opnns; i++) {
-    if (plmn->MCCdigit1 != _emm_data.opnn[i].plmn->MCCdigit1) {
+  for (i = 0; i < user->emm_data->n_opnns; i++) {
+    if (plmn->MCCdigit1 != user->emm_data->opnn[i].plmn->MCCdigit1) {
       continue;
     }
 
-    if (plmn->MCCdigit2 != _emm_data.opnn[i].plmn->MCCdigit2) {
+    if (plmn->MCCdigit2 != user->emm_data->opnn[i].plmn->MCCdigit2) {
       continue;
     }
 
-    if (plmn->MCCdigit3 != _emm_data.opnn[i].plmn->MCCdigit3) {
+    if (plmn->MCCdigit3 != user->emm_data->opnn[i].plmn->MCCdigit3) {
       continue;
     }
 
-    if (plmn->MNCdigit1 != _emm_data.opnn[i].plmn->MNCdigit1) {
+    if (plmn->MNCdigit1 != user->emm_data->opnn[i].plmn->MNCdigit1) {
       continue;
     }
 
-    if (plmn->MNCdigit2 != _emm_data.opnn[i].plmn->MNCdigit2) {
+    if (plmn->MNCdigit2 != user->emm_data->opnn[i].plmn->MNCdigit2) {
       continue;
     }
 
-    if (plmn->MNCdigit3 != _emm_data.opnn[i].plmn->MNCdigit3) {
+    if (plmn->MNCdigit3 != user->emm_data->opnn[i].plmn->MNCdigit3) {
       continue;
     }
 
@@ -1195,8 +1194,8 @@ static int _IdleMode_get_suitable_cell(nas_user_t *user, int 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" :
+            (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" :
+            (user->emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" :
             "Automatic/manual");
   /*
    * Notify EMM-AS SAP that cell information related to the given
@@ -1206,8 +1205,8 @@ static int _IdleMode_get_suitable_cell(nas_user_t *user, 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);
+  if (user->emm_data->plmn_rat != NET_ACCESS_UNAVAILABLE) {
+    emm_sap.u.emm_as.u.cell_info.rat = (1 << user->emm_data->plmn_rat);
   } else {
     emm_sap.u.emm_as.u.cell_info.rat = NET_ACCESS_UNAVAILABLE;
   }
diff --git a/openair3/NAS/UE/EMM/IdleMode.h b/openair3/NAS/UE/EMM/IdleMode.h
index f602cb37b060f208f8a20502a01c75a5cab46e5a..17b0eabee5b20ee5e0dab278ea248da85a8ae5da 100644
--- a/openair3/NAS/UE/EMM/IdleMode.h
+++ b/openair3/NAS/UE/EMM/IdleMode.h
@@ -51,7 +51,7 @@ Description Defines the functions used to get information from the list
 /************************  G L O B A L    T Y P E S  ************************/
 /****************************************************************************/
 
-typedef int (*IdleMode_callback_t) (int);
+typedef int (*IdleMode_callback_t) (emm_data_t *emm_data, int);
 
 /****************************************************************************/
 /********************  G L O B A L    V A R I A B L E S  ********************/
@@ -68,7 +68,7 @@ int IdleMode_get_hplmn_index(void);
 int IdleMode_get_rplmn_index(void);
 int IdleMode_get_splmn_index(void);
 
-int IdleMode_update_plmn_list(int index);
+int IdleMode_update_plmn_list(emm_data_t *emm_data, int i);
 
 const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index,
                                        size_t *len);
diff --git a/openair3/NAS/UE/EMM/LowerLayer.c b/openair3/NAS/UE/EMM/LowerLayer.c
index afe8f37c1bd910c774d284acb4275b942ba6305c..ab1d5c6cf89443879c2abef5b304b5c3ea9903f6 100644
--- a/openair3/NAS/UE/EMM/LowerLayer.c
+++ b/openair3/NAS/UE/EMM/LowerLayer.c
@@ -160,7 +160,7 @@ int lowerlayer_establish(nas_user_t *user)
   LOG_FUNC_IN;
 
   /* Update the EPS Connection Management status */
-  _emm_data.ecm_status = ECM_CONNECTED;
+  user->emm_data->ecm_status = ECM_CONNECTED;
 
   LOG_FUNC_RETURN (RETURNok);
 }
@@ -188,7 +188,7 @@ int lowerlayer_release(nas_user_t *user, int cause)
   int rc;
 
   /* Update the EPS Connection Management status */
-  _emm_data.ecm_status = ECM_IDLE;
+  user->emm_data->ecm_status = ECM_IDLE;
 
   emm_sap.primitive = EMMREG_LOWERLAYER_RELEASE;
   emm_sap.u.emm_reg.ueid = 0;
@@ -257,9 +257,9 @@ int lowerlayer_data_req(nas_user_t *user, unsigned int ueid, const OctetString *
   //struct emm_data_context_s *ctx  = NULL;
 
   emm_sap.primitive = EMMAS_DATA_REQ;
-  emm_sap.u.emm_as.u.data.guti = _emm_data.guti;
+  emm_sap.u.emm_as.u.data.guti = user->emm_data->guti;
   emm_sap.u.emm_as.u.data.ueid = 0;
-  sctx = _emm_data.security;
+  sctx = user->emm_data->security;
 
   emm_sap.u.emm_as.u.data.NASinfo = 0;
   emm_sap.u.emm_as.u.data.NASmsg.length = data->length;
diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c
index 7974f7c3c672984ede0da6157e92f3fce4b80729..0ea25dbe5f4ac0f8c7481b81da23c6798ea13afe 100644
--- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c
+++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c
@@ -108,8 +108,7 @@ int EmmDeregisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *evt)
        * Notify EMM that the MT is currently searching an operator
        * to register to
        */
-      // FIXME REVIEW
-      rc = emm_proc_registration_notify(NET_REG_STATE_ON);
+      rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_ON);
 
       if (rc != RETURNok) {
         LOG_TRACE(WARNING, "EMM-FSM   - "
diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c
index cea39a545636585020d3a1262476ecfb390856e9..bcf089e3cc5638b384a69108d0a25d118d7bf7d6 100644
--- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c
+++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c
@@ -95,7 +95,7 @@ int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt)
     /*
      * No suitable cell of the selected PLMN has been found to camp on
      */
-    rc = emm_proc_registration_notify(NET_REG_STATE_DENIED);
+    rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_DENIED);
 
     if (rc != RETURNok) {
       LOG_TRACE(WARNING, "EMM-FSM   - "
@@ -112,7 +112,7 @@ int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt)
      * may be selected either automatically or manually.
      * Or the user manually re-selected a PLMN to register to.
      */
-    rc = emm_proc_registration_notify(NET_REG_STATE_ON);
+    rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_ON);
 
     if (rc != RETURNok) {
       LOG_TRACE(WARNING, "EMM-FSM   - "
diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c
index 27b6979e049cf01cd5995f84e1340a5c203a3a80..1072e31319e7e1f9c7fb1d75a2e8a35b1140abef 100644
--- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c
+++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c
@@ -140,7 +140,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt)
       /*
        * Notify EMM that the MT is registered
        */
-      rc = emm_proc_registration_notify(NET_REG_STATE_HN);
+      rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_HN);
 
       if (rc != RETURNok) {
         LOG_TRACE(WARNING, "EMM-FSM   - "
@@ -167,7 +167,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt)
       /*
        * Notify EMM that the MT's registration is denied
        */
-      rc = emm_proc_registration_notify(NET_REG_STATE_DENIED);
+      rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_DENIED);
 
       if (rc != RETURNok) {
         LOG_TRACE(WARNING, "EMM-FSM   - "
diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c
index 8e0c661b094a1c02dd0e8f58626b42e25303e8f2..09a0397055a3c703e7f4506dd3ef1d7af3b7ed90 100644
--- a/openair3/NAS/UE/EMM/SAP/emm_as.c
+++ b/openair3/NAS/UE/EMM/SAP/emm_as.c
@@ -135,16 +135,16 @@ static int _emm_as_encrypt(
 
 static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg);
 
-static int _emm_as_security_res(const emm_as_security_t *,
+static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *,
                                 ul_info_transfer_req_t *);
-static int _emm_as_establish_req(const emm_as_establish_t *,
+static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *,
                                  nas_establish_req_t *);
 
 
 static int _emm_as_cell_info_req(const emm_as_cell_info_t *, cell_info_req_t *);
 
-static int _emm_as_data_req(const emm_as_data_t *msg, ul_info_transfer_req_t *);
-static int _emm_as_status_ind(const emm_as_status_t *, ul_info_transfer_req_t *);
+static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg, ul_info_transfer_req_t *);
+static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *, ul_info_transfer_req_t *);
 static int _emm_as_release_req(const emm_as_release_t *, nas_release_req_t *);
 
 /****************************************************************************/
@@ -321,7 +321,7 @@ static int _emm_as_recv(nas_user_t *user, unsigned int ueid, const char *msg, in
 
   emm_security_context_t       *security = NULL;    /* Current EPS NAS security context     */
 
-  security = _emm_data.security;
+  security = user->emm_data->security;
 
   /* Decode the received message */
   decoder_rc = nas_message_decode(msg, &nas_msg, len, security);
@@ -428,7 +428,7 @@ static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm
         memset(&header, 0, sizeof(header));
         /* Decrypt the received security protected message */
 
-        security = _emm_data.security;
+        security = user->emm_data->security;
         int bytes = nas_message_decrypt((char *)(msg->NASmsg.value),
                                         plain_msg,
                                         &header,
@@ -509,7 +509,7 @@ static int _emm_as_establish_cnf(nas_user_t *user, const emm_as_establish_t *msg
   decoder_rc = nas_message_decode((char *)(msg->NASmsg.value),
                                   &nas_msg,
                                   msg->NASmsg.length,
-                                  _emm_data.security);
+                                  user->emm_data->security);
 
   if (decoder_rc < 0) {
     LOG_TRACE(WARNING, "EMMAS-SAP - Failed to decode initial NAS message"
@@ -937,13 +937,13 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg)
 
   switch (msg->primitive) {
   case _EMMAS_DATA_REQ:
-    as_msg.msgID = _emm_as_data_req(
+    as_msg.msgID = _emm_as_data_req(user->emm_data,
                      &msg->u.data,
                      &as_msg.msg.ul_info_transfer_req);
     break;
 
   case _EMMAS_STATUS_IND:
-    as_msg.msgID = _emm_as_status_ind(
+    as_msg.msgID = _emm_as_status_ind(user->emm_data,
                      &msg->u.status,
                      &as_msg.msg.ul_info_transfer_req);
     break;
@@ -956,13 +956,13 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg)
 
 
   case _EMMAS_SECURITY_RES:
-    as_msg.msgID = _emm_as_security_res(
+    as_msg.msgID = _emm_as_security_res(user->emm_data,
                      &msg->u.security,
                      &as_msg.msg.ul_info_transfer_req);
     break;
 
   case _EMMAS_ESTABLISH_REQ:
-    as_msg.msgID = _emm_as_establish_req(
+    as_msg.msgID = _emm_as_establish_req(user->emm_data,
                      &msg->u.establish,
                      &as_msg.msg.nas_establish_req);
     break;
@@ -1065,7 +1065,7 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _emm_as_data_req(const emm_as_data_t *msg,
+static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg,
                             ul_info_transfer_req_t *as_msg)
 {
   LOG_FUNC_IN;
@@ -1112,7 +1112,7 @@ static int _emm_as_data_req(const emm_as_data_t *msg,
     int bytes;
     emm_security_context_t    *emm_security_context   = NULL;
 
-    emm_security_context = _emm_data.security;
+    emm_security_context = emm_data->security;
 
     if (emm_security_context) {
 
@@ -1161,7 +1161,7 @@ static int _emm_as_data_req(const emm_as_data_t *msg,
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _emm_as_status_ind(const emm_as_status_t *msg,
+static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *msg,
                               ul_info_transfer_req_t *as_msg)
 {
   LOG_FUNC_IN;
@@ -1193,7 +1193,7 @@ static int _emm_as_status_ind(const emm_as_status_t *msg,
   if (size > 0) {
     emm_security_context_t    *emm_security_context   = NULL;
 
-    emm_security_context = _emm_data.security;
+    emm_security_context = emm_data->security;
 
     if (emm_security_context) {
 
@@ -1275,7 +1275,7 @@ static int _emm_as_release_req(const emm_as_release_t *msg,
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _emm_as_security_res(const emm_as_security_t *msg,
+static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *msg,
                                 ul_info_transfer_req_t *as_msg)
 {
   LOG_FUNC_IN;
@@ -1340,7 +1340,7 @@ static int _emm_as_security_res(const emm_as_security_t *msg,
     int bytes = _emm_as_encode(&as_msg->nasMsg,
                                &nas_msg,
                                size,
-                               _emm_data.security);
+                               emm_data->security);
 
     if (bytes > 0) {
       LOG_FUNC_RETURN (AS_UL_INFO_TRANSFER_REQ);
@@ -1369,7 +1369,7 @@ static int _emm_as_security_res(const emm_as_security_t *msg,
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _emm_as_establish_req(const emm_as_establish_t *msg,
+static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *msg,
                                  nas_establish_req_t *as_msg)
 {
   LOG_FUNC_IN;
@@ -1433,7 +1433,7 @@ static int _emm_as_establish_req(const emm_as_establish_t *msg,
                   &as_msg->initialNasMsg,
                   &nas_msg,
                   size,
-                  _emm_data.security);
+                  emm_data->security);
 
     if (bytes > 0) {
       LOG_FUNC_RETURN (AS_NAS_ESTABLISH_REQ);
diff --git a/openair3/NAS/UE/EMM/SAP/emm_esm.c b/openair3/NAS/UE/EMM/SAP/emm_esm.c
index 10b34f0a1dc49bbf37e137abe72c74e596d8ca7d..b3a494ad49b5addc665917d78b7f607b47ca42fd 100644
--- a/openair3/NAS/UE/EMM/SAP/emm_esm.c
+++ b/openair3/NAS/UE/EMM/SAP/emm_esm.c
@@ -134,7 +134,7 @@ int emm_esm_send(nas_user_t *user, const emm_esm_t *msg)
       if (msg->u.establish.is_emergency) {
         /* Consider the UE attached for emergency bearer services
          * only */
-        rc = emm_proc_attach_set_emergency();
+        rc = emm_proc_attach_set_emergency(user->emm_data);
       }
     } else {
       /* Consider the UE locally detached from the network */
diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c
index 05f094b22dee1ea7517e2c65ba03a3bd1b34519c..1126f087dd73f0d9e79c03a3e13b214ec4f56ac6 100644
--- a/openair3/NAS/UE/EMM/SecurityModeControl.c
+++ b/openair3/NAS/UE/EMM/SecurityModeControl.c
@@ -163,8 +163,8 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
   /*
    * Check the replayed UE security capabilities
    */
-  uint8_t eea = (0x80 >> _emm_data.security->capability.eps_encryption);
-  uint8_t eia = (0x80 >> _emm_data.security->capability.eps_integrity);
+  uint8_t eea = (0x80 >> user->emm_data->security->capability.eps_encryption);
+  uint8_t eia = (0x80 >> user->emm_data->security->capability.eps_integrity);
 
   if ( (reea != eea) || (reia != eia) ) {
     LOG_TRACE(WARNING, "EMM-PROC  - Replayed UE security capabilities "
@@ -180,7 +180,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
   /*
    * Check the non-current EPS security context
    */
-  else if (_emm_data.non_current == NULL) {
+  else if (user->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;
@@ -191,37 +191,37 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
   else {
     LOG_TRACE(INFO, "EMM-PROC  - Update the non-current EPS security context seea=%u seia=%u", seea, seia);
     /* Update selected cyphering and integrity algorithms */
-    //LG COMENTED _emm_data.non_current->capability.encryption = seea;
-    //LG COMENTED _emm_data.non_current->capability.integrity  = seia;
+    //LG COMENTED user->emm_data->non_current->capability.encryption = seea;
+    //LG COMENTED user->emm_data->non_current->capability.integrity  = seia;
 
-    _emm_data.non_current->selected_algorithms.encryption = seea;
-    _emm_data.non_current->selected_algorithms.integrity = seia;
+    user->emm_data->non_current->selected_algorithms.encryption = seea;
+    user->emm_data->non_current->selected_algorithms.integrity = seia;
 
     /* Derive the NAS cyphering key */
-    if (_emm_data.non_current->knas_enc.value == NULL) {
-      _emm_data.non_current->knas_enc.value =
+    if (user->emm_data->non_current->knas_enc.value == NULL) {
+      user->emm_data->non_current->knas_enc.value =
         (uint8_t *)calloc(1,AUTH_KNAS_ENC_SIZE);
-      _emm_data.non_current->knas_enc.length = AUTH_KNAS_ENC_SIZE;
+      user->emm_data->non_current->knas_enc.length = AUTH_KNAS_ENC_SIZE;
     }
 
-    if (_emm_data.non_current->knas_enc.value != NULL) {
+    if (user->emm_data->non_current->knas_enc.value != NULL) {
       LOG_TRACE(INFO, "EMM-PROC  - Update the non-current EPS security context knas_enc");
-      rc = _security_knas_enc(&_emm_data.non_current->kasme,
-                              &_emm_data.non_current->knas_enc, seea);
+      rc = _security_knas_enc(&user->emm_data->non_current->kasme,
+                              &user->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 =
+    if (user->emm_data->non_current->knas_int.value == NULL) {
+      user->emm_data->non_current->knas_int.value =
         (uint8_t *)calloc(1,AUTH_KNAS_INT_SIZE);
-      _emm_data.non_current->knas_int.length = AUTH_KNAS_INT_SIZE;
+      user->emm_data->non_current->knas_int.length = AUTH_KNAS_INT_SIZE;
     }
 
-    if (_emm_data.non_current->knas_int.value != NULL) {
+    if (user->emm_data->non_current->knas_int.value != NULL) {
       if (rc != RETURNerror) {
         LOG_TRACE(INFO, "EMM-PROC  - Update the non-current EPS security context knas_int");
-        rc = _security_knas_int(&_emm_data.non_current->kasme,
-                                &_emm_data.non_current->knas_int, seia);
+        rc = _security_knas_int(&user->emm_data->non_current->kasme,
+                                &user->emm_data->non_current->knas_int, seia);
       }
     }
 
@@ -234,10 +234,10 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
     if (_security_data.kenb.value != NULL) {
       if (rc != RETURNerror) {
         LOG_TRACE(INFO, "EMM-PROC  - Update the non-current EPS security context kenb");
-        // LG COMMENT rc = _security_kenb(&_emm_data.security->kasme,
-        rc = _security_kenb(&_emm_data.non_current->kasme,
+        // LG COMMENT rc = _security_kenb(&user->emm_data->security->kasme,
+        rc = _security_kenb(&user->emm_data->non_current->kasme,
                             &_security_data.kenb,
-                            *(uint32_t *)(&_emm_data.non_current->ul_count));
+                            *(uint32_t *)(&user->emm_data->non_current->ul_count));
       }
     }
 
@@ -248,13 +248,13 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
       LOG_TRACE(INFO, "EMM-PROC  - NAS security mode command accepted by the UE");
 
       /* Update the current EPS security context */
-      if ( native_ksi && (_emm_data.security->type != EMM_KSI_NATIVE) ) {
+      if ( native_ksi && (user->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) ) {
+        if ( (user->emm_data->non_current->type == EMM_KSI_NATIVE) &&
+             (user->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
@@ -263,36 +263,37 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
           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;
+          _security_release(user->emm_data->security);
+          user->emm_data->security = user->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;
+          user->emm_data->security->ul_count.overflow = 0;
+          user->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) ) {
+      if ( !native_ksi && (user->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) {
+        if (ksi != user->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;
+          user->emm_data->security->ul_count.overflow = 0;
+          user->emm_data->security->ul_count.seq_num = 0;
         }
       }
 
-      _emm_data.security->selected_algorithms.encryption = seea;
-      _emm_data.security->selected_algorithms.integrity  = seia;
+      user->emm_data->security->selected_algorithms.encryption = seea;
+      user->emm_data->security->selected_algorithms.integrity  = seia;
 #if  defined(NAS_BUILT_IN_UE)
       nas_itti_kenb_refresh_req(_security_data.kenb.value);
 #endif
+
     }
     /*
      * NAS security mode command not accepted by the UE
@@ -326,14 +327,14 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
    */
   emm_sap_t emm_sap;
   emm_sap.primitive = EMMAS_SECURITY_RES;
-  emm_sap.u.emm_as.u.security.guti = _emm_data.guti;
+  emm_sap.u.emm_as.u.security.guti = user->emm_data->guti;
   emm_sap.u.emm_as.u.security.ueid = 0;
   emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_SMC;
   emm_sap.u.emm_as.u.security.imeisv_request = imeisv_request;
   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);
+                           user->emm_data->security, security_context_is_new, TRUE);
   rc = emm_sap_send(user, &emm_sap);
 
   LOG_FUNC_RETURN (rc);
diff --git a/openair3/NAS/UE/EMM/emmData.h b/openair3/NAS/UE/EMM/emmData.h
index df89fb0c8e04937c4d0243b49dca97a2de55d9ed..2618c44b83e44740b9893c09b950217c55f30509 100644
--- a/openair3/NAS/UE/EMM/emmData.h
+++ b/openair3/NAS/UE/EMM/emmData.h
@@ -333,13 +333,6 @@ typedef struct emm_data_s {
 /********************  G L O B A L    V A R I A B L E S  ********************/
 /****************************************************************************/
 
-/*
- * --------------------------------------------------------------------------
- *      EPS mobility management data (used within EMM only)
- * --------------------------------------------------------------------------
- */
-emm_data_t _emm_data;
-
 /*
  * --------------------------------------------------------------------------
  *      EPS mobility management timers – UE side
diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c
index e3342ed3baa141ea9ba56c24afe66d10f7ab8ff7..591c9e6b0fe93b27946fc1e0dd87314a1fe4d042 100644
--- a/openair3/NAS/UE/EMM/emm_main.c
+++ b/openair3/NAS/UE/EMM/emm_main.c
@@ -78,7 +78,7 @@ static usim_data_t _usim_data;
  * to the user application
  */
 static emm_indication_callback_t _emm_main_user_callback;
-static int _emm_main_callback(int);
+static int _emm_main_callback(emm_data_t *emm_data, int);
 
 /****************************************************************************/
 /******************  E X P O R T E D    F U N C T I O N S  ******************/
@@ -97,66 +97,70 @@ static int _emm_main_callback(int);
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    None                                       **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ***************************************************************************/
 void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const char *imei)
 {
   LOG_FUNC_IN;
-
+  user->emm_data = calloc(1, sizeof(emm_data_t));
+  if ( user->emm_data == NULL ) {
+    LOG_TRACE(ERROR, "EMM-MAIN  - Failed to get allocate emm_data");
+    // FIXME stop here
+  }
   /* USIM validity indicator */
-  _emm_data.usim_is_valid = FALSE;
+  user->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));
-  _emm_data.imei->length = _emm_main_get_imei(_emm_data.imei, imei);
+  user->emm_data->imei = (imei_t *)malloc(sizeof(imei_t));
+  user->emm_data->imei->length = _emm_main_get_imei(user->emm_data->imei, imei);
   /* The IMSI, valid only if USIM is present */
-  _emm_data.imsi = NULL;
+  user->emm_data->imsi = NULL;
   /* EPS location information */
-  _emm_data.guti = NULL;
-  _emm_data.tai = NULL;
-  _emm_data.ltai.n_tais = 0;
+  user->emm_data->guti = NULL;
+  user->emm_data->tai = NULL;
+  user->emm_data->ltai.n_tais = 0;
   /* EPS Connection Management status */
-  _emm_data.ecm_status = ECM_IDLE;
+  user->emm_data->ecm_status = ECM_IDLE;
   /* Network selection mode of operation */
-  _emm_data.plmn_mode = EMM_DATA_PLMN_AUTO;
+  user->emm_data->plmn_mode = EMM_DATA_PLMN_AUTO;
   /* Index of the PLMN manually selected by the user */
-  _emm_data.plmn_index = -1;
+  user->emm_data->plmn_index = -1;
   /* Selected Radio Access Technology */
-  _emm_data.plmn_rat = NET_ACCESS_UNAVAILABLE;
+  user->emm_data->plmn_rat = NET_ACCESS_UNAVAILABLE;
   /* Selected PLMN */
-  memset(&_emm_data.splmn, 0xFF, sizeof(plmn_t));
-  _emm_data.is_rplmn = FALSE;
-  _emm_data.is_eplmn = FALSE;
+  memset(&user->emm_data->splmn, 0xFF, sizeof(plmn_t));
+  user->emm_data->is_rplmn = FALSE;
+  user->emm_data->is_eplmn = FALSE;
   /* Radio Access Technology of the serving cell */
-  _emm_data.rat = NET_ACCESS_UNAVAILABLE;
+  user->emm_data->rat = NET_ACCESS_UNAVAILABLE;
   /* Network registration status */
-  _emm_data.stat = NET_REG_STATE_OFF;
-  _emm_data.is_attached = FALSE;
-  _emm_data.is_emergency = FALSE;
+  user->emm_data->stat = NET_REG_STATE_OFF;
+  user->emm_data->is_attached = FALSE;
+  user->emm_data->is_emergency = FALSE;
   /* Location/Tracking area code */
-  _emm_data.tac = 0;  // two byte in hexadecimal format
+  user->emm_data->tac = 0;  // two byte in hexadecimal format
   /* Identifier of the serving cell */
-  _emm_data.ci = 0;   // four byte in hexadecimal format
+  user->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);
+  memset(user->emm_data->plist.buffer, 0, EMM_DATA_BUFFER_SIZE + 1);
   /* Home PLMN */
-  memset(&_emm_data.hplmn, 0xFF, sizeof(plmn_t));
+  memset(&user->emm_data->hplmn, 0xFF, sizeof(plmn_t));
   /* List of Forbidden PLMNs */
-  _emm_data.fplmn.n_plmns = 0;
+  user->emm_data->fplmn.n_plmns = 0;
   /* List of Forbidden PLMNs for GPRS service */
-  _emm_data.fplmn_gprs.n_plmns = 0;
+  user->emm_data->fplmn_gprs.n_plmns = 0;
   /* List of Equivalent HPLMNs */
-  _emm_data.ehplmn.n_plmns = 0;
+  user->emm_data->ehplmn.n_plmns = 0;
   /* List of user controlled PLMNs */
-  _emm_data.plmn.n_plmns = 0;
+  user->emm_data->plmn.n_plmns = 0;
   /* List of operator controlled PLMNs */
-  _emm_data.oplmn.n_plmns = 0;
+  user->emm_data->oplmn.n_plmns = 0;
   /* List of operator network name records */
-  _emm_data.n_opnns = 0;
+  user->emm_data->n_opnns = 0;
   /* List of Forbidden Tracking Areas */
-  _emm_data.ftai.n_tais = 0;
+  user->emm_data->ftai.n_tais = 0;
   /* List of Forbidden Tracking Areas for roaming */
-  _emm_data.ftai_roaming.n_tais = 0;
+  user->emm_data->ftai_roaming.n_tais = 0;
 
   /*
    * Get USIM application data
@@ -170,47 +174,47 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c
 
     /* The USIM application is present and valid */
     LOG_TRACE(INFO, "EMM-MAIN  - USIM application data successfully read");
-    _emm_data.usim_is_valid = TRUE;
+    user->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;
+    user->emm_data->hplmn.MCCdigit1 = _usim_data.imsi.u.num.digit1;
+    user->emm_data->hplmn.MCCdigit2 = _usim_data.imsi.u.num.digit2;
+    user->emm_data->hplmn.MCCdigit3 = _usim_data.imsi.u.num.digit3;
+    user->emm_data->hplmn.MNCdigit1 = _usim_data.imsi.u.num.digit4;
+    user->emm_data->hplmn.MNCdigit2 = _usim_data.imsi.u.num.digit5;
+    user->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;
+        user->emm_data->fplmn.plmn[i] = _usim_data.fplmn[i];
+        user->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;
+        user->emm_data->ehplmn.plmn[i] = _usim_data.ehplmn[i];
+        user->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;
+        user->emm_data->plmn.plmn[i] = _usim_data.plmn[i].plmn;
+        user->emm_data->userAcT[i] = _usim_data.plmn[i].AcT;
+        user->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;
+        user->emm_data->oplmn.plmn[i] = _usim_data.oplmn[i].plmn;
+        user->emm_data->operAcT[i] = _usim_data.oplmn[i].AcT;
+        user->emm_data->oplmn.n_plmns += 1;
       }
     }
 
@@ -218,10 +222,10 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c
     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;
+        user->emm_data->opnn[i].plmn = &_usim_data.opl[i].plmn;
+        user->emm_data->opnn[i].fullname = (char *)_usim_data.pnn[pnn_id].fullname.value;
+        user->emm_data->opnn[i].shortname = (char *)_usim_data.pnn[pnn_id].shortname.value;
+        user->emm_data->n_opnns += 1;
       }
     }
 
@@ -229,78 +233,78 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c
 
     /* Get the EPS location information */
     if (PLMN_IS_VALID(_usim_data.epsloci.guti.gummei.plmn)) {
-      _emm_data.guti = &_usim_data.epsloci.guti;
+      user->emm_data->guti = &_usim_data.epsloci.guti;
     }
 
     if (TAI_IS_VALID(_usim_data.epsloci.tai)) {
-      _emm_data.tai = &_usim_data.epsloci.tai;
+      user->emm_data->tai = &_usim_data.epsloci.tai;
     }
 
-    _emm_data.status = _usim_data.epsloci.status;
+    user->emm_data->status = _usim_data.epsloci.status;
 
     /* Get NAS configuration parameters */
-    _emm_data.NAS_SignallingPriority =
+    user->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 =
+    user->emm_data->NMO_I_Behaviour = _usim_data.nasconfig.NMO_I_Behaviour.value[0];
+    user->emm_data->AttachWithImsi = _usim_data.nasconfig.AttachWithImsi.value[0];
+    user->emm_data->MinimumPeriodicSearchTimer =
       _usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0];
-    _emm_data.ExtendedAccessBarring =
+    user->emm_data->ExtendedAccessBarring =
       _usim_data.nasconfig.ExtendedAccessBarring.value[0];
-    _emm_data.Timer_T3245_Behaviour =
+    user->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 =
+    user->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));
+    if (user->emm_data->security != NULL) {
+      memset(user->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;
+        user->emm_data->security->type = EMM_KSI_NATIVE;
       } else {
-        _emm_data.security->type = EMM_KSI_NOT_AVAILABLE;
+        user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE;
       }
 
       /* EPS key set identifier */
-      _emm_data.security->eksi = _usim_data.securityctx.KSIasme.value[0];
+      user->emm_data->security->eksi = _usim_data.securityctx.KSIasme.value[0];
       /* ASME security key */
-      _emm_data.security->kasme.length =
+      user->emm_data->security->kasme.length =
         _usim_data.securityctx.Kasme.length;
-      _emm_data.security->kasme.value =
-        (uint8_t *)malloc(_emm_data.security->kasme.length);
+      user->emm_data->security->kasme.value =
+        (uint8_t *)malloc(user->emm_data->security->kasme.length);
 
-      if (_emm_data.security->kasme.value) {
-        memcpy(_emm_data.security->kasme.value,
+      if (user->emm_data->security->kasme.value) {
+        memcpy(user->emm_data->security->kasme.value,
                _usim_data.securityctx.Kasme.value,
-               _emm_data.security->kasme.length);
+               user->emm_data->security->kasme.length);
       }
 
       /* Downlink count parameter */
       if (_usim_data.securityctx.dlNAScount.length <= sizeof(uint32_t)) {
-        memcpy(&_emm_data.security->dl_count,
+        memcpy(&user->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,
+        memcpy(&user->emm_data->security->ul_count,
                _usim_data.securityctx.ulNAScount.value,
                _usim_data.securityctx.ulNAScount.length);
       }
 
       /* Ciphering algorithm */
-      _emm_data.security->capability.eps_encryption =
+      user->emm_data->security->capability.eps_encryption =
         ((_usim_data.securityctx.algorithmID.value[0] >> 4) & 0xf);
       /* Identity protection algorithm */
-      _emm_data.security->capability.eps_integrity =
+      user->emm_data->security->capability.eps_integrity =
         (_usim_data.securityctx.algorithmID.value[0] & 0xf);
       /* NAS integrity and cyphering keys are not available */
     } else {
@@ -311,8 +315,8 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c
     /*
      * 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;
+    memset(&user->emm_data->nvdata.rplmn, 0xFF, sizeof(plmn_t));
+    user->emm_data->nvdata.eplmn.n_plmns = 0;
     /* Get EMM data pathname */
     char *path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME);
 
@@ -320,29 +324,29 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c
       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));
+      int rc = memory_read(path, &user->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,
+        user->emm_data->imsi = &_usim_data.imsi;
+        int imsi_ok = _emm_main_imsi_cmp(&user->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],
+                    user->emm_data->nvdata.imsi.u.value[0],
+                    user->emm_data->nvdata.imsi.u.value[1],
+                    user->emm_data->nvdata.imsi.u.value[2],
+                    user->emm_data->nvdata.imsi.u.value[3],
+                    user->emm_data->nvdata.imsi.u.value[4],
+                    user->emm_data->nvdata.imsi.u.value[5],
+                    user->emm_data->nvdata.imsi.u.value[6],
+                    user->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],
@@ -351,8 +355,8 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c
                     _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;
+          memset(&user->emm_data->nvdata.rplmn, 0xFF, sizeof(plmn_t));
+          user->emm_data->nvdata.eplmn.n_plmns = 0;
         }
       }
 
@@ -392,6 +396,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c
   /*
    * Initialize EMM internal data used for UE in idle mode
    */
+    // FIXME REVIEW
   IdleMode_initialize(user, &_emm_main_callback);
 
   LOG_FUNC_OUT;
@@ -412,56 +417,14 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c
  **          Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-void emm_main_cleanup(void)
+void emm_main_cleanup(emm_data_t *emm_data)
 {
   LOG_FUNC_IN;
 
-  if (_emm_data.usim_is_valid) {
+  if (emm_data->usim_is_valid) {
     /*
      * 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");
-    }
-
-#endif
   }
 
   /*
@@ -474,7 +437,7 @@ void emm_main_cleanup(void)
   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));
+    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);
@@ -482,13 +445,13 @@ void emm_main_cleanup(void)
   }
 
   /* Release dynamically allocated memory */
-  if (_emm_data.imei) {
-    free(_emm_data.imei);
-    _emm_data.imei = NULL;
+  if (emm_data->imei) {
+    free(emm_data->imei);
+    emm_data->imei = NULL;
   }
 
-  if (_emm_data.security) {
-    emm_security_context_t *security = _emm_data.security;
+  if (emm_data->security) {
+    emm_security_context_t *security = emm_data->security;
 
     if (security->kasme.value) {
       free(security->kasme.value);
@@ -508,8 +471,8 @@ void emm_main_cleanup(void)
       security->knas_int.length = 0;
     }
 
-    free(_emm_data.security);
-    _emm_data.security = NULL;
+    free(emm_data->security);
+    emm_data->security = NULL;
   }
   LOG_FUNC_OUT;
 }
@@ -521,17 +484,17 @@ void emm_main_cleanup(void)
  ** Description: Get the International Mobile Subscriber Identity number   **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    Pointer to the IMSI                        **
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-const imsi_t *emm_main_get_imsi(void)
+const imsi_t *emm_main_get_imsi(emm_data_t *emm_data)
 {
   LOG_FUNC_IN;
-  LOG_FUNC_RETURN (&_emm_data.nvdata.imsi);
+  LOG_FUNC_RETURN (&emm_data->nvdata.imsi);
 }
 
 /****************************************************************************
@@ -572,10 +535,10 @@ const msisdn_t *emm_main_get_msisdn(void)
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ***************************************************************************/
-int emm_main_set_plmn_selection_mode(int mode, int format,
+int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format,
                                      const network_plmn_t *plmn, int rat)
 {
   LOG_FUNC_IN;
@@ -585,7 +548,7 @@ int emm_main_set_plmn_selection_mode(int mode, int format,
   LOG_TRACE(INFO, "EMM-MAIN  - PLMN selection: mode=%d, format=%d, plmn=%s, "
             "rat=%d", mode, format, (const char *)&plmn->id, rat);
 
-  _emm_data.plmn_mode = mode;
+  emm_data->plmn_mode = mode;
 
   if (mode != EMM_DATA_PLMN_AUTO) {
     /* Get the index of the PLMN in the list of available PLMNs */
@@ -596,8 +559,8 @@ int emm_main_set_plmn_selection_mode(int mode, int format,
                 (const char *)&plmn->id);
     } else {
       /* Update the manually selected network selection data */
-      _emm_data.plmn_index = index;
-      _emm_data.plmn_rat = rat;
+      emm_data->plmn_index = index;
+      emm_data->plmn_rat = rat;
     }
   } else {
     /*
@@ -619,17 +582,17 @@ int emm_main_set_plmn_selection_mode(int mode, int format,
  **      operation                                                 **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    The value of the network selection mode    **
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int emm_main_get_plmn_selection_mode(void)
+int emm_main_get_plmn_selection_mode(emm_data_t *emm_data)
 {
   LOG_FUNC_IN;
-  LOG_FUNC_RETURN (_emm_data.plmn_mode);
+  LOG_FUNC_RETURN (emm_data->plmn_mode);
 }
 
 /****************************************************************************
@@ -639,19 +602,19 @@ int emm_main_get_plmn_selection_mode(void)
  ** Description: Get the list of available PLMNs                           **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ** 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(emm_data_t *emm_data, const char **plist)
 {
   LOG_FUNC_IN;
 
-  int size = IdleMode_update_plmn_list(0);
-  *plist = _emm_data.plist.buffer;
+  int size = IdleMode_update_plmn_list(emm_data, 0);
+  *plist = emm_data->plist.buffer;
 
   LOG_FUNC_RETURN (size);
 }
@@ -664,7 +627,6 @@ int emm_main_get_plmn_list(const char **plist)
  **                                                                        **
  ** 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                           **
@@ -673,7 +635,7 @@ int emm_main_get_plmn_list(const char **plist)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format)
+const char *emm_main_get_selected_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format)
 {
   LOG_FUNC_IN;
 
@@ -684,7 +646,7 @@ 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,
+    const char *name = _emm_main_get_plmn(&emm_data->splmn, index,
                                           format, &size);
 
     if (size > 0) {
@@ -703,7 +665,6 @@ const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format)
  **                                                                        **
  ** 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                       **
@@ -712,7 +673,7 @@ const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format)
+const char *emm_main_get_registered_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format)
 {
   LOG_FUNC_IN;
 
@@ -724,7 +685,7 @@ 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,
+    const char *name = _emm_main_get_plmn(&emm_data->nvdata.rplmn,
                                           index, format, &size);
 
     if (size > 0) {
@@ -744,17 +705,16 @@ const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format)
  **      registration of the UE                                    **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _emm_data                                  **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    The current network registration status    **
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-Stat_t emm_main_get_plmn_status(void)
+Stat_t emm_main_get_plmn_status(emm_data_t *emm_data)
 {
   LOG_FUNC_IN;
-  LOG_FUNC_RETURN (_emm_data.stat);
+  LOG_FUNC_RETURN (emm_data->stat);
 }
 
 /****************************************************************************
@@ -765,17 +725,16 @@ Stat_t emm_main_get_plmn_status(void)
  **      belongs to                                                **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _emm_data                                  **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    The Location/Tracking area code            **
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-tac_t emm_main_get_plmn_tac(void)
+tac_t emm_main_get_plmn_tac(emm_data_t *emm_data)
 {
   LOG_FUNC_IN;
-  LOG_FUNC_RETURN (_emm_data.tac);
+  LOG_FUNC_RETURN (emm_data->tac);
 }
 
 /****************************************************************************
@@ -785,17 +744,16 @@ tac_t emm_main_get_plmn_tac(void)
  ** Description: Get the identifier of the serving cell                    **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _emm_data                                  **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    The serving cell identifier                **
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-ci_t emm_main_get_plmn_ci(void)
+ci_t emm_main_get_plmn_ci(emm_data_t *emm_data)
 {
   LOG_FUNC_IN;
-  LOG_FUNC_RETURN (_emm_data.ci);
+  LOG_FUNC_RETURN (emm_data->ci);
 }
 
 /****************************************************************************
@@ -806,7 +764,6 @@ ci_t emm_main_get_plmn_ci(void)
  **      ving cell                                                 **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _emm_data                                  **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    The value of the Radio Access Technology   **
@@ -814,10 +771,10 @@ ci_t emm_main_get_plmn_ci(void)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-AcT_t emm_main_get_plmn_rat(void)
+AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data)
 {
   LOG_FUNC_IN;
-  LOG_FUNC_RETURN (_emm_data.rat);
+  LOG_FUNC_RETURN (emm_data->rat);
 }
 
 /****************************************************************************
@@ -828,7 +785,7 @@ AcT_t emm_main_get_plmn_rat(void)
  **      network for EPS services or emergency service only        **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    TRUE if the UE is currently attached to    **
@@ -836,10 +793,10 @@ AcT_t emm_main_get_plmn_rat(void)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int emm_main_is_attached(void)
+int emm_main_is_attached(emm_data_t *emm_data)
 {
   LOG_FUNC_IN;
-  LOG_FUNC_RETURN (_emm_data.is_attached);
+  LOG_FUNC_RETURN (emm_data->is_attached);
 }
 
 /****************************************************************************
@@ -850,7 +807,7 @@ int emm_main_is_attached(void)
  **      network for emergency bearer services                     **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _emm_data                                  **
+ **      Others:    user->emm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    TRUE if the UE is currently attached or is **
@@ -859,10 +816,10 @@ int emm_main_is_attached(void)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int emm_main_is_emergency(void)
+int emm_main_is_emergency(emm_data_t *emm_data)
 {
   LOG_FUNC_IN;
-  LOG_FUNC_RETURN (_emm_data.is_attached && _emm_data.is_emergency);
+  LOG_FUNC_RETURN (emm_data->is_attached && emm_data->is_emergency);
 }
 
 /****************************************************************************/
@@ -881,21 +838,21 @@ int emm_main_is_emergency(void)
  **             present in the network. The list has to be **
  **             displayed to the user application when     **
  **             size > 0.                                  **
- **          Others:    _emm_data                                  **
+ **          Others:    user->emm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
  **          Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _emm_main_callback(int size)
+static int _emm_main_callback(emm_data_t *emm_data, int size)
 {
   LOG_FUNC_IN;
 
   /* 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);
+  int rc = (*_emm_main_user_callback)(emm_data->stat, emm_data->tac,
+                                      emm_data->ci, emm_data->rat,
+                                      emm_data->plist.buffer, size);
 
   LOG_FUNC_RETURN (rc);
 }
diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h
index 403a87507d20081fb8bfa8566d8b8bce0a123c40..dfb8049f07f10f38df16d1395bff1d96f84a1073 100644
--- a/openair3/NAS/UE/EMM/emm_main.h
+++ b/openair3/NAS/UE/EMM/emm_main.h
@@ -70,32 +70,32 @@ typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t,
 
 void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const char *imei);
 
-void emm_main_cleanup(void);
+void emm_main_cleanup(emm_data_t *emm_data);
 
 
 /* User's getter of UE's identity */
-const imsi_t *emm_main_get_imsi(void);
+const imsi_t *emm_main_get_imsi(emm_data_t *emm_data);
 
 /* User's getter of the subscriber dialing number */
 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,
+int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format,
                                      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_selection_mode(emm_data_t *emm_data);
+int emm_main_get_plmn_list(emm_data_t *emm_data, const char **plist);
+const char *emm_main_get_selected_plmn(emm_data_t *emm_data, 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);
+Stat_t emm_main_get_plmn_status(emm_data_t *emm_data);
+tac_t emm_main_get_plmn_tac(emm_data_t *emm_data);
+ci_t emm_main_get_plmn_ci(emm_data_t *emm_data);
+AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data);
+const char *emm_main_get_registered_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format);
 
 /* User's getter for network attachment */
-int emm_main_is_attached(void);
-int emm_main_is_emergency(void);
+int emm_main_is_attached(emm_data_t *emm_data);
+int emm_main_is_emergency(emm_data_t *emm_data);
 
 
 #endif /* __EMM_MAIN_H__*/
diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h
index 8bfe447e509f5f60a1ece01563c30ec004d6326e..0aaf76dfa093362247f14cf1691968bb7621275e 100644
--- a/openair3/NAS/UE/EMM/emm_proc.h
+++ b/openair3/NAS/UE/EMM/emm_proc.h
@@ -133,7 +133,7 @@ int emm_proc_attach_failure(int is_initial, void *args);
 int emm_proc_attach_release(void *args);
 int emm_proc_attach_restart(nas_user_t *user);
 
-int emm_proc_attach_set_emergency(void);
+int emm_proc_attach_set_emergency(emm_data_t *emm_data);
 // FIXME check prototype
 int emm_proc_attach_set_detach(void *user);
 
@@ -183,8 +183,8 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, in
  *             Network indication handlers
  *---------------------------------------------------------------------------
  */
-int emm_proc_registration_notify(Stat_t status);
-int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat);
-int emm_proc_network_notify(int index);
+int emm_proc_registration_notify(emm_data_t *emm_data, Stat_t status);
+int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat);
+int emm_proc_network_notify(emm_data_t *emm_data, int index);
 
 #endif /* __EMM_PROC_H__*/
diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c
index 68304f087906ca2fce21ca3425f8e453bd1cbeb8..ee7b4f52c0fa5a3404ff96dea5c32406a52383fc 100644
--- a/openair3/NAS/UE/nas_proc.c
+++ b/openair3/NAS/UE/nas_proc.c
@@ -134,7 +134,7 @@ void nas_proc_cleanup(nas_user_t *user)
 
 
   /* Perform the EPS Mobility Manager's clean up procedure */
-  emm_main_cleanup();
+  emm_main_cleanup(user->emm_data);
 
   /* Perform the EPS Session Manager's clean up procedure */
   esm_main_cleanup(user->esm_data);
@@ -251,11 +251,11 @@ int nas_proc_get_eps(nas_user_t *user, int *stat)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int nas_proc_get_imsi(char *imsi_str)
+int nas_proc_get_imsi(emm_data_t *emm_data, char *imsi_str)
 {
   LOG_FUNC_IN;
 
-  const imsi_t *imsi = emm_main_get_imsi();
+  const imsi_t *imsi = emm_main_get_imsi(emm_data);
 
   if (imsi != NULL) {
     int offset = 0;
@@ -386,7 +386,7 @@ int nas_proc_register(nas_user_t *user, int mode, int format, const network_plmn
   /*
    * Set the PLMN selection mode of operation
    */
-  int index = emm_main_set_plmn_selection_mode(mode, format, oper, AcT);
+  int index = emm_main_set_plmn_selection_mode(user->emm_data, mode, format, oper, AcT);
 
   if ( !(index < 0) ) {
     /*
@@ -452,16 +452,16 @@ int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format
   LOG_FUNC_IN;
 
   /* Get the PLMN selection mode of operation */
-  *mode = emm_main_get_plmn_selection_mode();
+  *mode = emm_main_get_plmn_selection_mode(user->emm_data);
 
   /* Get the currently selected operator */
-  const char *oper_name = emm_main_get_selected_plmn(oper, format);
+  const char *oper_name = emm_main_get_selected_plmn(user->emm_data, oper, format);
 
   if (oper_name != NULL) {
     /* An operator is currently selected */
     *selected = TRUE;
     /* Get the supported Radio Access Technology */
-    *AcT = emm_main_get_plmn_rat();
+    *AcT = emm_main_get_plmn_rat(user->emm_data);
   } else {
     /* No any operator is selected */
     *selected = FALSE;
@@ -489,7 +489,7 @@ int nas_proc_get_oper_list(nas_user_t *user, const char **oper_list)
 {
   LOG_FUNC_IN;
 
-  int size = emm_main_get_plmn_list(oper_list);
+  int size = emm_main_get_plmn_list(user->emm_data, oper_list);
 
   LOG_FUNC_RETURN (size);
 }
@@ -514,7 +514,7 @@ int nas_proc_get_reg_status(nas_user_t *user, int *stat)
 {
   LOG_FUNC_IN;
 
-  *stat = emm_main_get_plmn_status();
+  *stat = emm_main_get_plmn_status(user->emm_data);
 
   LOG_FUNC_RETURN (RETURNok);
 }
@@ -542,9 +542,9 @@ int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT)
 {
   LOG_FUNC_IN;
 
-  sprintf(tac, "%.4x", emm_main_get_plmn_tac());  // two byte
-  sprintf(ci, "%.8x", emm_main_get_plmn_ci());    // four byte
-  *AcT = emm_main_get_plmn_rat();             // E-UTRAN
+  sprintf(tac, "%.4x", emm_main_get_plmn_tac(user->emm_data));  // two byte
+  sprintf(ci, "%.8x", emm_main_get_plmn_ci(user->emm_data));    // four byte
+  *AcT = emm_main_get_plmn_rat(user->emm_data);             // E-UTRAN
 
   LOG_FUNC_RETURN (RETURNok);
 }
@@ -570,7 +570,7 @@ int nas_proc_detach(nas_user_t *user, int switch_off)
   emm_sap_t emm_sap;
   int rc = RETURNok;
 
-  if ( emm_main_is_attached() ) {
+  if ( emm_main_is_attached(user->emm_data) ) {
     /* Initiate an Detach procedure */
     emm_sap.primitive = EMMREG_DETACH_INIT;
     emm_sap.u.emm_reg.u.detach.switch_off = switch_off;
@@ -601,7 +601,7 @@ int nas_proc_attach(nas_user_t *user)
   emm_sap_t emm_sap;
   int rc = RETURNok;
 
-  if ( !emm_main_is_attached() ) {
+  if ( !emm_main_is_attached(user->emm_data) ) {
     /* Initiate an Attach procedure */
     emm_sap.primitive = EMMREG_ATTACH_INIT;
     emm_sap.u.emm_reg.u.attach.is_emergency = FALSE;
@@ -630,7 +630,7 @@ int nas_proc_get_attach_status(nas_user_t *user)
 {
   LOG_FUNC_IN;
 
-  int is_attached = emm_main_is_attached();
+  int is_attached = emm_main_is_attached(user->emm_data);
 
   LOG_FUNC_RETURN (is_attached);
 }
@@ -950,14 +950,14 @@ int nas_proc_activate_pdn(nas_user_t *user, int cid)
 
   int rc = RETURNok;
 
-  if ( !emm_main_is_attached() ) {
+  if ( !emm_main_is_attached(user->emm_data) ) {
     /*
      * If the UE is not attached to the network, perform EPS attach
      * procedure prior to attempt to request any PDN connectivity
      */
     LOG_TRACE(WARNING, "NAS-PROC  - UE is not attached to the network");
     rc = nas_proc_attach(user);
-  } else if (emm_main_is_emergency()) {
+  } else if (emm_main_is_emergency(user->emm_data)) {
     /* The UE is attached for emergency bearer services; It shall not
      * request a PDN connection to any other PDN */
     LOG_TRACE(WARNING,"NAS-PROC  - Attached for emergency bearer services");
diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h
index ec1ca3f3c78f28ea83d5d4288d28b3363ab912fa..672488aee6b96ca10e1ae3f9ed0169d710757781 100644
--- a/openair3/NAS/UE/nas_proc.h
+++ b/openair3/NAS/UE/nas_proc.h
@@ -76,7 +76,7 @@ int nas_proc_enable_s1_mode(nas_user_t *user);
 int nas_proc_disable_s1_mode(nas_user_t *user);
 int nas_proc_get_eps(nas_user_t *user, int *stat);
 
-int nas_proc_get_imsi(char *imsi_str);
+int nas_proc_get_imsi(emm_data_t *emm_data, char *imsi_str);
 int nas_proc_get_msisdn(char *msisdn_str, int *ton_npi);
 
 int nas_proc_get_signal_quality(nas_user_t *user, int *rsrq, int *rsrp);
diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c
index 827003699c4cfa51ba904be702c8c5e5bfef0376..63aae7e8c2390b6374d71eff363134bb07739321 100644
--- a/openair3/NAS/UE/nas_user.c
+++ b/openair3/NAS/UE/nas_user.c
@@ -652,7 +652,7 @@ static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data)
     }
 
     /* Get the International Mobile Subscriber Identity (IMSI) */
-    ret_code = nas_proc_get_imsi(cimi->IMSI);
+    ret_code = nas_proc_get_imsi(user->emm_data, cimi->IMSI);
 
     if (ret_code != RETURNok) {
       LOG_TRACE(ERROR, "USR-MAIN  - Failed to get IMSI number");
diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h
index a963960f4fe9c970c457c6aba1a6ebb670bd3192..05ce952f2200faa0bd0f765b9e0a0b0543acaf03 100644
--- a/openair3/NAS/UE/user_defs.h
+++ b/openair3/NAS/UE/user_defs.h
@@ -49,14 +49,16 @@ Description NAS type definition to manage a user equipment
 #include "esmData.h"
 #include "esm_pt_defs.h"
 #include "EMM/emm_fsm_defs.h"
+#include "EMM/emmData.h"
 
 typedef struct {
   int fd;
   proc_data_t proc;
   esm_data_t *esm_data; // ESM internal data (used within ESM only)
   esm_pt_data_t *esm_pt_data;
-  emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status
   esm_ebr_data_t *esm_ebr_data;  // EPS bearer contexts
+  emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status
+  emm_data_t *emm_data; // EPS mobility management data
 } nas_user_t;
 
 #endif