From 1d75a2476aef18bb0e02efaaa17130ab2deabec7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= <frederic.leroy@b-com.com>
Date: Wed, 6 Jul 2016 08:19:23 +0200
Subject: [PATCH] UE/ESM: Make _esm_data a pointer instance
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch adds esm_data_t parameter to ESM functions.
This fixes a bug where the old _esm_data was redefined in all .o

Signed-off-by: Frédéric Leroy <frederic.leroy@b-com.com>
---
 .../ESM/DedicatedEpsBearerContextActivation.c |  10 +-
 .../ESM/DefaultEpsBearerContextActivation.c   |  10 +-
 .../NAS/UE/ESM/EpsBearerContextDeactivation.c |  28 ++--
 openair3/NAS/UE/ESM/PdnConnectivity.c         | 134 +++++++++---------
 openair3/NAS/UE/ESM/PdnDisconnect.c           |  33 ++---
 openair3/NAS/UE/ESM/SAP/esm_recv.c            |  20 +--
 openair3/NAS/UE/ESM/SAP/esm_recv.h            |  10 +-
 openair3/NAS/UE/ESM/SAP/esm_sap.c             |  35 ++---
 openair3/NAS/UE/ESM/esmData.h                 |   2 +-
 openair3/NAS/UE/ESM/esm_ebr_context.c         |  24 ++--
 openair3/NAS/UE/ESM/esm_ebr_context.h         |   8 +-
 openair3/NAS/UE/ESM/esm_main.c                | 107 +++++++-------
 openair3/NAS/UE/ESM/esm_main.h                |  17 +--
 openair3/NAS/UE/ESM/esm_proc.h                |  18 +--
 openair3/NAS/UE/nas_proc.c                    |  38 ++---
 openair3/NAS/UE/nas_proc.h                    |   7 +-
 openair3/NAS/UE/nas_user.c                    |   6 +-
 17 files changed, 258 insertions(+), 249 deletions(-)

diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c
index 6a9e140ad..2fb53bb61 100755
--- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c
+++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c
@@ -111,7 +111,7 @@ Description Defines the dedicated EPS bearer context activation ESM
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi,
+int esm_proc_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int ebi, int default_ebi,
     const esm_proc_qos_t *qos,
     const esm_proc_tft_t *tft,
     int *esm_cause)
@@ -124,7 +124,7 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi,
             "requested by the network (ebi=%d)", ebi);
 
   /* Get the PDN connection the dedicated EPS bearer is linked to */
-  int pid = esm_ebr_context_get_pid(default_ebi);
+  int pid = esm_ebr_context_get_pid(esm_data, default_ebi);
 
   if (pid < 0) {
     /* 3GPP TS 24.301, section 6.4.2.5, abnormal case c
@@ -148,7 +148,7 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi,
     int old_pid, old_bid;
     /* Locally deactivate the existing EPS bearer context and proceed
      * with the requested dedicated EPS bearer context activation */
-    rc = esm_proc_eps_bearer_context_deactivate(TRUE, ebi,
+    rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE, ebi,
          &old_pid, &old_bid);
 
     if (rc != RETURNok) {
@@ -162,7 +162,7 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi,
 
   if (ebi != ESM_EBI_UNASSIGNED) {
     /* Check syntactical errors in packet filters */
-    rc = esm_ebr_context_check_tft(pid, ebi, tft,
+    rc = esm_ebr_context_check_tft(esm_data, pid, ebi, tft,
                                    ESM_EBR_CONTEXT_TFT_CREATE);
 
     if (rc != RETURNok) {
@@ -172,7 +172,7 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi,
       *esm_cause = ESM_CAUSE_SYNTACTICAL_ERROR_IN_PACKET_FILTER;
     } else {
       /* Create new dedicated EPS bearer context */
-      default_ebi = esm_ebr_context_create(pid, ebi, FALSE, qos, tft);
+      default_ebi = esm_ebr_context_create(esm_data, pid, ebi, FALSE, qos, tft);
 
       if (default_ebi != ESM_EBI_UNASSIGNED) {
         /* Dedicated EPS bearer contextx successfully created */
diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c
index 188459043..422f31511 100755
--- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c
+++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c
@@ -111,7 +111,7 @@ static struct {
  **      Others:    _default_eps_bearer_context_data           **
  **                                                                        **
  ***************************************************************************/
-int esm_proc_default_eps_bearer_context_request(int pid, int ebi,
+int esm_proc_default_eps_bearer_context_request(esm_data_t *esm_data, int pid, int ebi,
     const esm_proc_qos_t *qos,
     int *esm_cause)
 {
@@ -133,7 +133,7 @@ int esm_proc_default_eps_bearer_context_request(int pid, int ebi,
     int old_pid, old_bid;
     /* Locally deactivate the existing EPS bearer context and proceed
      * with the requested default EPS bearer context activation */
-    rc = esm_proc_eps_bearer_context_deactivate(TRUE, ebi,
+    rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE, ebi,
          &old_pid, &old_bid);
 
     if (rc != RETURNok) {
@@ -147,7 +147,7 @@ int esm_proc_default_eps_bearer_context_request(int pid, int ebi,
 
   if (ebi != ESM_EBI_UNASSIGNED) {
     /* Create new default EPS bearer context */
-    ebi = esm_ebr_context_create(pid, ebi, TRUE, qos, NULL);
+    ebi = esm_ebr_context_create(esm_data, pid, ebi, TRUE, qos, NULL);
 
     if (ebi != ESM_EBI_UNASSIGNED) {
       /* Default EPS bearer contextx successfully created */
@@ -353,7 +353,7 @@ int esm_proc_default_eps_bearer_context_complete(void)
  **      Others:    _default_eps_bearer_context_data           **
  **                                                                        **
  ***************************************************************************/
-int esm_proc_default_eps_bearer_context_failure(void)
+int esm_proc_default_eps_bearer_context_failure(esm_data_t *esm_data)
 {
   LOG_FUNC_IN;
 
@@ -364,7 +364,7 @@ int esm_proc_default_eps_bearer_context_failure(void)
             "ESM-PROC  - Default EPS bearer context activation failure");
 
   /* Release the default EPS bearer context and enter state INACTIVE */
-  int rc = esm_proc_eps_bearer_context_deactivate(TRUE, ebi, &pid, &bid);
+  int rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE, ebi, &pid, &bid);
 
   if (rc != RETURNerror) {
     /* Reset default EPS bearer context internal data */
diff --git a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c
index bceeebeff..36628618e 100755
--- a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c
+++ b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c
@@ -81,7 +81,7 @@ Description Defines the EPS bearer context deactivation ESM procedure
  * in the UE
  * --------------------------------------------------------------------------
  */
-static int _eps_bearer_release(int ebi, int *pid, int *bid);
+static int _eps_bearer_release(esm_data_t *esm_data, int ebi, int *pid, int *bid);
 
 
 /****************************************************************************/
@@ -119,7 +119,7 @@ static int _eps_bearer_release(int ebi, int *pid, int *bid);
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi,
+int esm_proc_eps_bearer_context_deactivate(esm_data_t *esm_data, int is_local, int ebi,
     int *pid, int *bid)
 {
   LOG_FUNC_IN;
@@ -130,14 +130,14 @@ int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi,
   if (is_local) {
     if (ebi != ESM_SAP_ALL_EBI) {
       /* Locally release the EPS bearer context */
-      rc = _eps_bearer_release(ebi, pid, bid);
+      rc = _eps_bearer_release(esm_data, ebi, pid, bid);
     } else {
       /* Locally release all the EPS bearer contexts */
       *bid = 0;
 
       for (*pid = 0; *pid < ESM_DATA_PDN_MAX; (*pid)++) {
-        if (_esm_data.pdn[*pid].data) {
-          rc = _eps_bearer_release(ESM_EBI_UNASSIGNED, pid, bid);
+        if (esm_data->pdn[*pid].data) {
+          rc = _eps_bearer_release(esm_data, ESM_EBI_UNASSIGNED, pid, bid);
 
           if (rc != RETURNok) {
             break;
@@ -153,17 +153,17 @@ int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi,
             ebi);
 
   if (*pid < ESM_DATA_PDN_MAX) {
-    if (_esm_data.pdn[*pid].pid != *pid) {
+    if (esm_data->pdn[*pid].pid != *pid) {
       LOG_TRACE(ERROR, "ESM-PROC  - PDN connection identifier %d "
                 "is not valid", *pid);
-    } else if (_esm_data.pdn[*pid].data == NULL) {
+    } else if (esm_data->pdn[*pid].data == NULL) {
       LOG_TRACE(ERROR, "ESM-PROC  - PDN connection %d has not been "
                 "allocated", *pid);
-    } else if (!_esm_data.pdn[*pid].is_active) {
+    } else if (!esm_data->pdn[*pid].is_active) {
       LOG_TRACE(WARNING, "ESM-PROC  - PDN connection %d is not active",
                 *pid);
     } else {
-      esm_pdn_t *pdn = _esm_data.pdn[*pid].data;
+      esm_pdn_t *pdn = esm_data->pdn[*pid].data;
 
       for (i = 0; i < pdn->n_bearers; i++) {
         if (pdn->bearer[i]->ebi != ebi) {
@@ -196,7 +196,7 @@ int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi,
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause)
+int esm_proc_eps_bearer_context_deactivate_request(esm_data_t *esm_data, int ebi, int *esm_cause)
 {
   LOG_FUNC_IN;
 
@@ -207,7 +207,7 @@ int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause)
             "requested by the network (ebi=%d)", ebi);
 
   /* Release the EPS bearer context entry */
-  if (esm_ebr_context_release(ebi, &pid, &bid) == ESM_EBI_UNASSIGNED) {
+  if (esm_ebr_context_release(esm_data, ebi, &pid, &bid) == ESM_EBI_UNASSIGNED) {
     LOG_TRACE(WARNING, "ESM-PROC  - Failed to release EPS bearer context");
     *esm_cause = ESM_CAUSE_PROTOCOL_ERROR;
     LOG_FUNC_RETURN (RETURNerror);
@@ -229,7 +229,7 @@ int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause)
                 "connection reactivation");
 
       /* Get PDN context parameters */
-      rc = esm_main_get_pdn(pid + 1, &esm_sap.data.pdn_connect.pdn_type,
+      rc = esm_main_get_pdn(esm_data, pid + 1, &esm_sap.data.pdn_connect.pdn_type,
                             &esm_sap.data.pdn_connect.apn,
                             &esm_sap.data.pdn_connect.is_emergency,
                             &active);
@@ -359,14 +359,14 @@ int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi,
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _eps_bearer_release(int ebi, int *pid, int *bid)
+static int _eps_bearer_release(esm_data_t *esm_data, int ebi, int *pid, int *bid)
 {
   LOG_FUNC_IN;
 
   int rc = RETURNerror;
 
   /* Release the EPS bearer context entry */
-  ebi = esm_ebr_context_release(ebi, pid, bid);
+  ebi = esm_ebr_context_release(esm_data, ebi, pid, bid);
 
   if (ebi == ESM_EBI_UNASSIGNED) {
     LOG_TRACE(WARNING, "ESM-PROC  - Failed to release EPS bearer context");
diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c
index 8c9d12320..b1a9af5d1 100755
--- a/openair3/NAS/UE/ESM/PdnConnectivity.c
+++ b/openair3/NAS/UE/ESM/PdnConnectivity.c
@@ -88,15 +88,15 @@ Description Defines the PDN connectivity ESM procedure executed by the
 /*
  * PDN connection handlers
  */
-static int _pdn_connectivity_create(int pid, const OctetString *apn,
+static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetString *apn,
                                     esm_proc_pdn_type_t pdn_type, int is_emergency);
-static int _pdn_connectivity_update(int pid, const OctetString *apn,
+static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetString *apn,
                                     esm_proc_pdn_type_t pdn_type, const OctetString *pdn_addr, int esm_cause);
-static int _pdn_connectivity_delete(int pid);
+static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid);
 
-static int _pdn_connectivity_set_pti(int pid, int pti);
-static int _pdn_connectivity_find_apn(const OctetString *apn);
-static int _pdn_connectivity_find_pdn(const OctetString *apn,
+static int _pdn_connectivity_set_pti(esm_data_t *esm_data, int pid, int pti);
+static int _pdn_connectivity_find_apn(esm_data_t *esm_data, const OctetString *apn);
+static int _pdn_connectivity_find_pdn(esm_data_t * esm_data, const OctetString *apn,
                                       esm_proc_pdn_type_t pdn_type);
 
 /*
@@ -141,7 +141,7 @@ static void *_pdn_connectivity_t3482_handler(void *);
  **      Others:    _esm_data                                  **
  **                                                                        **
  ***************************************************************************/
-int esm_proc_pdn_connectivity(int cid, int is_to_define,
+int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int is_to_define,
                               esm_proc_pdn_type_t pdn_type,
                               const OctetString *apn, int is_emergency,
                               unsigned int *pti)
@@ -154,7 +154,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define,
   if (!is_to_define) {
     LOG_TRACE(INFO, "ESM-PROC  - Undefine PDN connection (cid=%d)", cid);
     /* Delete the PDN connection entry */
-    int pti = _pdn_connectivity_delete(pid);
+    int pti = _pdn_connectivity_delete(esm_data, pid);
 
     if (pti != ESM_PT_UNASSIGNED) {
       /* Release the procedure transaction data */
@@ -175,7 +175,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define,
     }
 
     /* Update the PDN connection data */
-    rc = _pdn_connectivity_set_pti(pid, *pti);
+    rc = _pdn_connectivity_set_pti(esm_data, pid, *pti);
 
     if (rc != RETURNok) {
       LOG_TRACE(WARNING, "ESM-PROC  - Failed to update PDN connection");
@@ -189,14 +189,14 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define,
             (pdn_type == ESM_PDN_TYPE_IPV6)? "IPv6" : "IPv4v6",
             apn->value, cid);
 
-  if (is_emergency && _esm_data.emergency) {
+  if (is_emergency && esm_data->emergency) {
     /* The UE shall not request additional PDN connection for
      * emergency bearer services */
     LOG_TRACE(WARNING, "ESM-PROC  - PDN connection for emergency bearer "
               "services is already active");
     LOG_FUNC_RETURN (RETURNerror);
   } else if (pid < ESM_DATA_PDN_MAX) {
-    if ((pid == _esm_data.pdn[pid].pid) && (_esm_data.pdn[pid].is_active)) {
+    if ((pid == esm_data->pdn[pid].pid) && (esm_data->pdn[pid].is_active)) {
       /* PDN connection with the specified identifier is active */
       LOG_TRACE(WARNING, "ESM-PROC  - PDN connection is active");
       LOG_FUNC_RETURN (RETURNerror);
@@ -208,15 +208,15 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define,
 
   if (apn && apn->length > 0) {
     /* The UE requested subsequent connectivity to additionnal PDNs */
-    int pid = _pdn_connectivity_find_apn(apn);
+    int pid = _pdn_connectivity_find_apn(esm_data, apn);
 
-    if ( (pid >= 0) && _esm_data.pdn[pid].is_active ) {
+    if ( (pid >= 0) && esm_data->pdn[pid].is_active ) {
       /* An active PDN connection to this APN already exists */
-      if ( (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV4V6) &&
-           (_esm_data.pdn[pid].data->type != pdn_type) ) {
+      if ( (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4V6) &&
+           (esm_data->pdn[pid].data->type != pdn_type) ) {
         /* The UE is requesting PDN connection for other IP version
          * than the one already activated */
-        if (!_esm_data.pdn[pid].data->addr_realloc) {
+        if (!esm_data->pdn[pid].data->addr_realloc) {
           /* The network does not allow PDN connectivity using
            * IPv4 and IPv6 address versions to the same APN */
           if (pdn_type != ESM_PDN_TYPE_IPV4V6) {
@@ -227,7 +227,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define,
           } else {
             LOG_TRACE(WARNING, "ESM-PROC  - %s PDN connection to %s "
                       "already exists",
-                      (_esm_data.pdn[pid].data->type !=
+                      (esm_data->pdn[pid].data->type !=
                        ESM_PDN_TYPE_IPV4)? "IPv6" : "IPv4",
                       apn->value);
           }
@@ -239,8 +239,8 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define,
          * same IP version than the one already activated */
         LOG_TRACE(WARNING, "ESM-PROC  - %s PDN connection to %s "
                   "already exists",
-                  (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV4)?
-                  (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV6)?
+                  (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)?
+                  (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV6)?
           "IPv4v6" : "IPv6" : "IPv4", apn->value);
         LOG_FUNC_RETURN (RETURNerror);
       }
@@ -255,7 +255,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define,
    * not already established, or may have been allowed to request PDN
    * connectivity for other IP version than the one already activated
    */
-  rc = _pdn_connectivity_create(pid, apn, pdn_type, is_emergency);
+  rc = _pdn_connectivity_create(esm_data, pid, apn, pdn_type, is_emergency);
   LOG_FUNC_RETURN(rc);
 }
 
@@ -353,7 +353,7 @@ int esm_proc_pdn_connectivity_request(int is_standalone, int pti,
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type,
+int esm_proc_pdn_connectivity_accept(esm_data_t *esm_data, int pti, esm_proc_pdn_type_t pdn_type,
                                      const OctetString *pdn_addr,
                                      const OctetString *apn, int *esm_cause)
 {
@@ -398,7 +398,7 @@ int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type,
      */
 
     /* Check whether a PDN connection exists to this APN */
-    pid = _pdn_connectivity_find_pdn(apn, pdn_type);
+    pid = _pdn_connectivity_find_pdn(esm_data, apn, pdn_type);
 
     if (pid < 0) {
       /* No any PDN connection has been defined to establish connectivity
@@ -410,7 +410,7 @@ int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type,
     }
 
     /* Update the PDN connection */
-    rc = _pdn_connectivity_update(pid, apn, pdn_type, pdn_addr, *esm_cause);
+    rc = _pdn_connectivity_update(esm_data, pid, apn, pdn_type, pdn_addr, *esm_cause);
 
     if (rc != RETURNok) {
       LOG_TRACE(WARNING, "ESM-PROC  - Failed to update PDN connection "
@@ -690,7 +690,7 @@ static void *_pdn_connectivity_t3482_handler(void *args)
  **      Others:    _esm_data                                  **
  **                                                                        **
  ***************************************************************************/
-static int _pdn_connectivity_create(int pid, const OctetString *apn,
+static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetString *apn,
                                     esm_proc_pdn_type_t pdn_type,
                                     int is_emergency)
 {
@@ -700,14 +700,14 @@ static int _pdn_connectivity_create(int pid, const OctetString *apn,
 
   if (pid >= ESM_DATA_PDN_MAX) {
     return (RETURNerror);
-  } else if (_esm_data.pdn[pid].is_active) {
+  } else if (esm_data->pdn[pid].is_active) {
     LOG_TRACE(ERROR, "ESM-PROC  - PDN connection is active");
     return (RETURNerror);
   }
 
-  if (_esm_data.pdn[pid].data != NULL) {
+  if (esm_data->pdn[pid].data != NULL) {
     /* Update existing non-active PDN connection */
-    pdn = _esm_data.pdn[pid].data;
+    pdn = esm_data->pdn[pid].data;
   } else {
     /* Create new PDN connection */
     pdn = (esm_pdn_t *)malloc(sizeof(esm_pdn_t));
@@ -720,13 +720,13 @@ static int _pdn_connectivity_create(int pid, const OctetString *apn,
 
     memset(pdn, 0, sizeof(esm_pdn_t));
     /* Increment the number of PDN connections */
-    _esm_data.n_pdns += 1;
+    esm_data->n_pdns += 1;
     /* Set the PDN connection identifier */
-    _esm_data.pdn[pid].pid = pid;
+    esm_data->pdn[pid].pid = pid;
     /* Reset the PDN connection active indicator */
-    _esm_data.pdn[pid].is_active = FALSE;
+    esm_data->pdn[pid].is_active = FALSE;
     /* Setup the PDN connection data */
-    _esm_data.pdn[pid].data = pdn;
+    esm_data->pdn[pid].data = pdn;
   }
 
   /* Update the PDN connection data */
@@ -770,7 +770,7 @@ static int _pdn_connectivity_create(int pid, const OctetString *apn,
  **      Others:    _esm_data                                  **
  **                                                                        **
  ***************************************************************************/
-static int _pdn_connectivity_update(int pid, const OctetString *apn,
+static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetString *apn,
                                     esm_proc_pdn_type_t pdn_type,
                                     const OctetString *pdn_addr,
                                     int esm_cause)
@@ -779,21 +779,21 @@ static int _pdn_connectivity_update(int pid, const OctetString *apn,
 
   if (pid >= ESM_DATA_PDN_MAX) {
     return (RETURNerror);
-  } else if (pid != _esm_data.pdn[pid].pid) {
+  } else if (pid != esm_data->pdn[pid].pid) {
     LOG_TRACE(ERROR, "ESM-PROC  - PDN connection identifier is not valid");
     return (RETURNerror);
-  } else if (_esm_data.pdn[pid].data == NULL) {
+  } else if (esm_data->pdn[pid].data == NULL) {
     LOG_TRACE(ERROR, "ESM-PROC  - PDN connection has not been allocated");
     return (RETURNerror);
-  } else if (_esm_data.pdn[pid].is_active) {
+  } else if (esm_data->pdn[pid].is_active) {
     LOG_TRACE(WARNING, "ESM-PROC  - Active %s PDN connection to %s already "
-              "exists", (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV4)?
-              "IPv6" : "IPv4", _esm_data.pdn[pid].data->apn.value);
+              "exists", (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)?
+              "IPv6" : "IPv4", esm_data->pdn[pid].data->apn.value);
     return (RETURNerror);
   }
 
   /* Get the PDN connection */
-  esm_pdn_t *pdn = _esm_data.pdn[pid].data;
+  esm_pdn_t *pdn = esm_data->pdn[pid].data;
 
   /* Setup the Access Point Name value */
   if ( apn && (apn->length > 0) ) {
@@ -864,39 +864,39 @@ static int _pdn_connectivity_update(int pid, const OctetString *apn,
  **      Others:    _esm_data                                  **
  **                                                                        **
  ***************************************************************************/
-static int _pdn_connectivity_delete(int pid)
+static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid)
 {
   int pti = ESM_PT_UNASSIGNED;
 
   if (pid < ESM_DATA_PDN_MAX) {
-    if (pid != _esm_data.pdn[pid].pid) {
+    if (pid != esm_data->pdn[pid].pid) {
       LOG_TRACE(ERROR,
                 "ESM-PROC  - PDN connection identifier is not valid");
-    } else if (_esm_data.pdn[pid].data == NULL) {
+    } else if (esm_data->pdn[pid].data == NULL) {
       LOG_TRACE(ERROR,
                 "ESM-PROC  - PDN connection has not been allocated");
-    } else if (_esm_data.pdn[pid].is_active) {
+    } else if (esm_data->pdn[pid].is_active) {
       LOG_TRACE(ERROR, "ESM-PROC  - PDN connection is active");
     } else {
       /* Get the identity of the procedure transaction that created
        * the PDN connection */
-      pti = _esm_data.pdn[pid].data->pti;
+      pti = esm_data->pdn[pid].data->pti;
     }
   }
 
   if (pti != ESM_PT_UNASSIGNED) {
     /* Decrement the number of PDN connections */
-    _esm_data.n_pdns -= 1;
+    esm_data->n_pdns -= 1;
     /* Set the PDN connection as available */
-    _esm_data.pdn[pid].pid = -1;
+    esm_data->pdn[pid].pid = -1;
 
     /* Release allocated PDN connection data */
-    if (_esm_data.pdn[pid].data->apn.length > 0) {
-      free(_esm_data.pdn[pid].data->apn.value);
+    if (esm_data->pdn[pid].data->apn.length > 0) {
+      free(esm_data->pdn[pid].data->apn.value);
     }
 
-    free(_esm_data.pdn[pid].data);
-    _esm_data.pdn[pid].data = NULL;
+    free(esm_data->pdn[pid].data);
+    esm_data->pdn[pid].data = NULL;
     LOG_TRACE(WARNING, "ESM-PROC  - PDN connection %d released", pid);
   }
 
@@ -920,21 +920,21 @@ static int _pdn_connectivity_delete(int pid)
  **      Others:    _esm_data                                  **
  **                                                                        **
  ***************************************************************************/
-static int _pdn_connectivity_set_pti(int pid, int pti)
+static int _pdn_connectivity_set_pti(esm_data_t *esm_data, int pid, int pti)
 {
   if (pid < ESM_DATA_PDN_MAX) {
-    if (pid != _esm_data.pdn[pid].pid) {
+    if (pid != esm_data->pdn[pid].pid) {
       LOG_TRACE(ERROR,
                 "ESM-PROC  - PDN connection identifier is not valid");
-    } else if (_esm_data.pdn[pid].data == NULL) {
+    } else if (esm_data->pdn[pid].data == NULL) {
       LOG_TRACE(ERROR,
                 "ESM-PROC  - PDN connection has not been allocated");
-    } else if (_esm_data.pdn[pid].is_active) {
+    } else if (esm_data->pdn[pid].is_active) {
       LOG_TRACE(ERROR, "ESM-PROC  - PDN connection is active");
     } else {
       /* Update the identity of the procedure transaction assigned to
        * the PDN connection */
-      _esm_data.pdn[pid].data->pti = pti;
+      esm_data->pdn[pid].data->pti = pti;
       return (RETURNok);
     }
   }
@@ -958,17 +958,17 @@ static int _pdn_connectivity_set_pti(int pid, int pti)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _pdn_connectivity_find_apn(const OctetString *apn)
+static int _pdn_connectivity_find_apn(esm_data_t *esm_data, const OctetString *apn)
 {
   int i;
 
   for (i = 0; i < ESM_DATA_PDN_MAX; i++) {
-    if ( (_esm_data.pdn[i].pid != -1) && _esm_data.pdn[i].data ) {
-      if (_esm_data.pdn[i].data->apn.length != apn->length) {
+    if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) {
+      if (esm_data->pdn[i].data->apn.length != apn->length) {
         continue;
       }
 
-      if (memcmp(_esm_data.pdn[i].data->apn.value,
+      if (memcmp(esm_data->pdn[i].data->apn.value,
                  apn->value, apn->length) != 0) {
         continue;
       }
@@ -979,7 +979,7 @@ static int _pdn_connectivity_find_apn(const OctetString *apn)
   }
 
   /* Return the identifier of the PDN connection */
-  return (_esm_data.pdn[i].pid);
+  return (esm_data->pdn[i].pid);
 }
 
 /****************************************************************************
@@ -999,38 +999,38 @@ static int _pdn_connectivity_find_apn(const OctetString *apn)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _pdn_connectivity_find_pdn(const OctetString *apn,
+static int _pdn_connectivity_find_pdn(esm_data_t *esm_data, const OctetString *apn,
                                       const esm_proc_pdn_type_t pdn_type)
 {
   int i;
 
   for (i = 0; i < ESM_DATA_PDN_MAX; i++) {
-    if ( (_esm_data.pdn[i].pid != -1) && _esm_data.pdn[i].data ) {
+    if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) {
       /* PDN connection established during initial network attachment */
-      if (_esm_data.pdn[i].data->apn.length == 0) {
+      if (esm_data->pdn[i].data->apn.length == 0) {
         break;
       }
 
       /* Subsequent PDN connection established for the specified APN */
-      if (_esm_data.pdn[i].data->apn.length != apn->length) {
+      if (esm_data->pdn[i].data->apn.length != apn->length) {
         continue;
       }
 
-      if (memcmp(_esm_data.pdn[i].data->apn.value,
+      if (memcmp(esm_data->pdn[i].data->apn.value,
                  apn->value, apn->length) != 0) {
         continue;
       }
 
-      if (_esm_data.pdn[i].data->type == ESM_PDN_TYPE_IPV4V6) {
+      if (esm_data->pdn[i].data->type == ESM_PDN_TYPE_IPV4V6) {
         break;
       }
 
-      if (_esm_data.pdn[i].data->type == pdn_type) {
+      if (esm_data->pdn[i].data->type == pdn_type) {
         break;
       }
     }
   }
 
   /* Return the identifier of the PDN connection */
-  return (_esm_data.pdn[i].pid);
+  return (esm_data->pdn[i].pid);
 }
diff --git a/openair3/NAS/UE/ESM/PdnDisconnect.c b/openair3/NAS/UE/ESM/PdnDisconnect.c
index e9ab748f8..c5f9011e5 100755
--- a/openair3/NAS/UE/ESM/PdnDisconnect.c
+++ b/openair3/NAS/UE/ESM/PdnDisconnect.c
@@ -80,7 +80,7 @@ Description Defines the PDN disconnect ESM procedure executed by the
 /*
  * PDN disconnection handlers
  */
-static int _pdn_disconnect_get_default_ebi(int pti);
+static int _pdn_disconnect_get_default_ebi(esm_data_t *esm_data, int pti);
 
 /*
  * Timer handlers
@@ -121,7 +121,7 @@ static void *_pdn_disconnect_t3492_handler(void *);
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_proc_pdn_disconnect(int cid, unsigned int *pti, unsigned int *ebi)
+int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, unsigned int *ebi)
 {
   LOG_FUNC_IN;
 
@@ -129,21 +129,21 @@ int esm_proc_pdn_disconnect(int cid, unsigned int *pti, unsigned int *ebi)
   int pid = cid - 1;
 
   if (pid < ESM_DATA_PDN_MAX) {
-    if (pid != _esm_data.pdn[pid].pid) {
+    if (pid != esm_data->pdn[pid].pid) {
       LOG_TRACE(WARNING, "ESM-PROC  - PDN connection identifier %d is "
                 "not valid", pid);
-    } else if (_esm_data.pdn[pid].data == NULL) {
+    } else if (esm_data->pdn[pid].data == NULL) {
       LOG_TRACE(ERROR, "ESM-PROC  - PDN connection %d has not been "
                 "allocated", pid);
-    } else if (!_esm_data.pdn[pid].is_active) {
+    } else if (!esm_data->pdn[pid].is_active) {
       LOG_TRACE(WARNING, "ESM-PROC  - PDN connection is not active");
     } else {
       /* Get the procedure transaction identity assigned to the PDN
        * connection to be released */
-      *pti = _esm_data.pdn[pid].data->pti;
+      *pti = esm_data->pdn[pid].data->pti;
       /* Get the EPS bearer identity of the default bearer associated
        * with the PDN to disconnect from */
-      *ebi = _esm_data.pdn[pid].data->bearer[0]->ebi;
+      *ebi = esm_data->pdn[pid].data->bearer[0]->ebi;
       rc = RETURNok;
     }
   }
@@ -291,7 +291,7 @@ int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause)
+int esm_proc_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int *esm_cause)
 {
   LOG_FUNC_IN;
 
@@ -320,7 +320,7 @@ int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause)
     } else if (*esm_cause != ESM_CAUSE_LAST_PDN_DISCONNECTION_NOT_ALLOWED) {
       /* Get the identity of the default EPS bearer context allocated to
        * the PDN connection entry assigned to this procedure transaction */
-      int ebi = _pdn_disconnect_get_default_ebi(pti);
+      int ebi = _pdn_disconnect_get_default_ebi(esm_data, pti);
 
       if (ebi < 0) {
         LOG_TRACE(ERROR, "ESM-PROC  - No default EPS bearer found");
@@ -389,7 +389,8 @@ int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause)
 static void *_pdn_disconnect_t3492_handler(void *args)
 {
   LOG_FUNC_IN;
-
+  // FIXME check callback call
+  esm_data_t *esm_data = args;;
   int rc;
 
   /* Get retransmission timer parameters data */
@@ -438,7 +439,7 @@ static void *_pdn_disconnect_t3492_handler(void *args)
         /* Get the identity of the default EPS bearer context
          * allocated to the PDN connection entry assigned to
          * this procedure transaction */
-        int ebi = _pdn_disconnect_get_default_ebi(data->pti);
+        int ebi = _pdn_disconnect_get_default_ebi(esm_data, data->pti);
 
         if (ebi < 0) {
           LOG_TRACE(ERROR, "ESM-PROC  - No default EPS bearer found");
@@ -486,22 +487,22 @@ static void *_pdn_disconnect_t3492_handler(void *args)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _pdn_disconnect_get_default_ebi(int pti)
+static int _pdn_disconnect_get_default_ebi(esm_data_t *esm_data, int pti)
 {
   int ebi = -1;
   int i;
 
   for (i = 0; i < ESM_DATA_PDN_MAX; i++) {
-    if ( (_esm_data.pdn[i].pid != -1) && _esm_data.pdn[i].data ) {
-      if (_esm_data.pdn[i].data->pti != pti) {
+    if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) {
+      if (esm_data->pdn[i].data->pti != pti) {
         continue;
       }
 
       /* PDN entry found */
-      if (_esm_data.pdn[i].data->bearer[0] != NULL) {
+      if (esm_data->pdn[i].data->bearer[0] != NULL) {
         /* Get the EPS bearer identity of the default EPS bearer
          * context associated to the PDN connection */
-        ebi = _esm_data.pdn[i].data->bearer[0]->ebi;
+        ebi = esm_data->pdn[i].data->bearer[0]->ebi;
       }
 
       break;
diff --git a/openair3/NAS/UE/ESM/SAP/esm_recv.c b/openair3/NAS/UE/ESM/SAP/esm_recv.c
index 72b322e96..059478af9 100755
--- a/openair3/NAS/UE/ESM/SAP/esm_recv.c
+++ b/openair3/NAS/UE/ESM/SAP/esm_recv.c
@@ -142,7 +142,7 @@ int esm_recv_status(int pti, int ebi, const esm_status_msg *msg)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_recv_pdn_connectivity_reject(int pti, int ebi,
+int esm_recv_pdn_connectivity_reject(esm_data_t *esm_data, int pti, int ebi,
                                      const pdn_connectivity_reject_msg *msg)
 {
   LOG_FUNC_IN;
@@ -213,7 +213,7 @@ int esm_recv_pdn_connectivity_reject(int pti, int ebi,
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_recv_pdn_disconnect_reject(int pti, int ebi,
+int esm_recv_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int ebi,
                                    const pdn_disconnect_reject_msg *msg)
 {
   LOG_FUNC_IN;
@@ -257,7 +257,7 @@ int esm_recv_pdn_disconnect_reject(int pti, int ebi,
   esm_cause = msg->esmcause;
 
   /* Execute the PDN disconnect procedure not accepted by the network */
-  int rc = esm_proc_pdn_disconnect_reject(pti, &esm_cause);
+  int rc = esm_proc_pdn_disconnect_reject(esm_data, pti, &esm_cause);
 
   if (rc != RETURNerror) {
     esm_cause = ESM_CAUSE_SUCCESS;
@@ -285,7 +285,7 @@ int esm_recv_pdn_disconnect_reject(int pti, int ebi,
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi,
+int esm_recv_activate_default_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi,
     const activate_default_eps_bearer_context_request_msg *msg)
 {
   LOG_FUNC_IN;
@@ -376,14 +376,14 @@ int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi,
   }
 
   /* Execute the PDN connectivity procedure accepted by the network */
-  int pid = esm_proc_pdn_connectivity_accept(pti, pdn_type,
+  int pid = esm_proc_pdn_connectivity_accept(esm_data, pti, pdn_type,
             &msg->pdnaddress.pdnaddressinformation,
             &msg->accesspointname.accesspointnamevalue,
             &esm_cause);
 
   if (pid != RETURNerror) {
     /* Create local default EPS bearer context */
-    int rc = esm_proc_default_eps_bearer_context_request(pid, ebi, &qos,
+    int rc = esm_proc_default_eps_bearer_context_request(esm_data, pid, ebi, &qos,
              &esm_cause);
 
     if (rc != RETURNerror) {
@@ -413,7 +413,7 @@ int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi,
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi,
+int esm_recv_activate_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi,
     const activate_dedicated_eps_bearer_context_request_msg *msg)
 {
   LOG_FUNC_IN;
@@ -587,7 +587,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi,
   }
 
   /* Execute the dedicated EPS bearer context activation procedure */
-  int rc = esm_proc_dedicated_eps_bearer_context_request(ebi,
+  int rc = esm_proc_dedicated_eps_bearer_context_request(esm_data, ebi,
            msg->linkedepsbeareridentity,
            &qos, &tft, &esm_cause);
 
@@ -621,7 +621,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi,
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_recv_deactivate_eps_bearer_context_request(int pti, int ebi,
+int esm_recv_deactivate_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi,
     const deactivate_eps_bearer_context_request_msg *msg)
 {
   LOG_FUNC_IN;
@@ -677,7 +677,7 @@ int esm_recv_deactivate_eps_bearer_context_request(int pti, int ebi,
 
   if (rc != RETURNerror) {
     /* Execute the EPS bearer context deactivation procedure */
-    rc = esm_proc_eps_bearer_context_deactivate_request(ebi, &esm_cause);
+    rc = esm_proc_eps_bearer_context_deactivate_request(esm_data, ebi, &esm_cause);
 
     if (rc != RETURNerror) {
       esm_cause = ESM_CAUSE_SUCCESS;
diff --git a/openair3/NAS/UE/ESM/SAP/esm_recv.h b/openair3/NAS/UE/ESM/SAP/esm_recv.h
index 35e3ee49c..76ba2b78e 100755
--- a/openair3/NAS/UE/ESM/SAP/esm_recv.h
+++ b/openair3/NAS/UE/ESM/SAP/esm_recv.h
@@ -95,23 +95,23 @@ int esm_recv_status(int pti, int ebi, const esm_status_msg *msg);
  * Transaction related messages
  * ----------------------------
  */
-int esm_recv_pdn_connectivity_reject(int pti, int ebi,
+int esm_recv_pdn_connectivity_reject(esm_data_t *esm_data, int pti, int ebi,
                                      const pdn_connectivity_reject_msg *msg);
 
-int esm_recv_pdn_disconnect_reject(int pti, int ebi,
+int esm_recv_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int ebi,
                                    const pdn_disconnect_reject_msg *msg);
 
 /*
  * Messages related to EPS bearer contexts
  * ---------------------------------------
  */
-int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi,
+int esm_recv_activate_default_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi,
     const activate_default_eps_bearer_context_request_msg *msg);
 
-int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi,
+int esm_recv_activate_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi,
     const activate_dedicated_eps_bearer_context_request_msg *msg);
 
-int esm_recv_deactivate_eps_bearer_context_request(int pti, int ebi,
+int esm_recv_deactivate_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi,
     const deactivate_eps_bearer_context_request_msg *msg);
 
 
diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.c b/openair3/NAS/UE/ESM/SAP/esm_sap.c
index d23aa0739..57c0f0328 100755
--- a/openair3/NAS/UE/ESM/SAP/esm_sap.c
+++ b/openair3/NAS/UE/ESM/SAP/esm_sap.c
@@ -70,7 +70,8 @@ Description Defines the ESM Service Access Points at which the EPS
 /*******************  L O C A L    D E F I N I T I O N S  *******************/
 /****************************************************************************/
 
-static int _esm_sap_recv(int msg_type, int is_standalone,
+// FIXME NOT SURE FOR THIS ONE
+static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone,
                          const OctetString *req, OctetString *rsp, esm_sap_error_t *err);
 static int _esm_sap_send(int msg_type, int is_standalone, int pti, int ebi,
                          const esm_sap_data_t *data, OctetString *rsp);
@@ -154,6 +155,8 @@ void esm_sap_initialize(void)
 int esm_sap_send(esm_sap_t *msg)
 {
   LOG_FUNC_IN;
+  // FIXME
+  esm_data_t *esm_data = _esm_data;
 
   int rc = RETURNerror;
   int pid;
@@ -179,7 +182,7 @@ int esm_sap_send(esm_sap_t *msg)
       }
 
       /* Define new PDN context */
-      rc = esm_proc_pdn_connectivity(pdn_connect->cid, TRUE,
+      rc = esm_proc_pdn_connectivity(esm_data, pdn_connect->cid, TRUE,
                                      pdn_connect->pdn_type, &apn,
                                      pdn_connect->is_emergency, NULL);
 
@@ -191,7 +194,7 @@ int esm_sap_send(esm_sap_t *msg)
     if (pdn_connect->is_defined) {
       unsigned int pti;
       /* Assign new procedure transaction identity */
-      rc = esm_proc_pdn_connectivity(pdn_connect->cid, TRUE,
+      rc = esm_proc_pdn_connectivity(esm_data, pdn_connect->cid, TRUE,
                                      pdn_connect->pdn_type, NULL,
                                      pdn_connect->is_emergency, &pti);
 
@@ -213,12 +216,12 @@ int esm_sap_send(esm_sap_t *msg)
 
       if ( msg->is_standalone && pdn_connect->is_defined ) {
         /* Undefine the specified PDN context */
-        rc = esm_proc_pdn_connectivity(pdn_connect->cid, FALSE,
+        rc = esm_proc_pdn_connectivity(esm_data, pdn_connect->cid, FALSE,
                                        pdn_connect->pdn_type, NULL,
                                        pdn_connect->is_emergency, NULL);
       } else if (msg->recv != NULL) {
         /* The UE received a PDN connectivity reject message */
-        rc = _esm_sap_recv(PDN_CONNECTIVITY_REJECT, msg->is_standalone,
+        rc = _esm_sap_recv(esm_data, PDN_CONNECTIVITY_REJECT, msg->is_standalone,
                            msg->recv, &msg->send, &msg->err);
       } else {
         /* The PDN connectivity procedure locally failed */
@@ -233,7 +236,7 @@ int esm_sap_send(esm_sap_t *msg)
     /* Get the procedure transaction identity and the EPS bearer
      * identity of the default bearer assigned to the PDN to
      * disconnect from */
-    rc = esm_proc_pdn_disconnect(msg->data.pdn_disconnect.cid,
+    rc = esm_proc_pdn_disconnect(esm_data, msg->data.pdn_disconnect.cid,
                                  &pti, &ebi);
 
     if (rc != RETURNerror) {
@@ -261,7 +264,7 @@ int esm_sap_send(esm_sap_t *msg)
 
   case ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REQ:
     /* The UE received activate default ESP bearer context request */
-    rc = _esm_sap_recv(ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST,
+    rc = _esm_sap_recv(esm_data, ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST,
                        msg->is_standalone,
                        msg->recv, &msg->send, &msg->err);
     break;
@@ -283,7 +286,7 @@ int esm_sap_send(esm_sap_t *msg)
     /*
      * Default ESP bearer context activation procedure locally failed
      */
-    rc = esm_proc_default_eps_bearer_context_failure();
+    rc = esm_proc_default_eps_bearer_context_failure(esm_data);
 
     if (rc != RETURNerror) {
       rc = esm_proc_pdn_connectivity_failure(FALSE);
@@ -314,7 +317,7 @@ int esm_sap_send(esm_sap_t *msg)
     /*
      * Locally deactivate EPS bearer context
      */
-    rc = esm_proc_eps_bearer_context_deactivate(TRUE,
+    rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE,
          msg->data.eps_bearer_context_deactivate.ebi, &pid, &bid);
   }
   break;
@@ -323,7 +326,7 @@ int esm_sap_send(esm_sap_t *msg)
     break;
 
   case ESM_UNITDATA_IND:
-    rc = _esm_sap_recv(-1, msg->is_standalone, msg->recv,
+    rc = _esm_sap_recv(esm_data, -1, msg->is_standalone, msg->recv,
                        &msg->send, &msg->err);
     break;
 
@@ -368,7 +371,7 @@ int esm_sap_send(esm_sap_t *msg)
  **      Others:    _esm_sap_buffer                            **
  **                                                                        **
  ***************************************************************************/
-static int _esm_sap_recv(int msg_type, int is_standalone,
+static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone,
                          const OctetString *req, OctetString *rsp,
                          esm_sap_error_t *err)
 {
@@ -446,7 +449,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone,
        * received from the MME
        */
       esm_cause = esm_recv_activate_default_eps_bearer_context_request(
-                    pti, ebi,
+                    esm_data, pti, ebi,
                     &esm_msg.activate_default_eps_bearer_context_request);
 
       if ( (esm_cause == ESM_CAUSE_SUCCESS) ||
@@ -484,7 +487,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone,
        * received from the MME
        */
       esm_cause = esm_recv_activate_dedicated_eps_bearer_context_request(
-                    pti, ebi,
+                    esm_data, pti, ebi,
                     &esm_msg.activate_dedicated_eps_bearer_context_request);
 
       if ( (esm_cause == ESM_CAUSE_SUCCESS) ||
@@ -524,7 +527,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone,
        * Process deactivate EPS bearer context request message
        * received from the MME
        */
-      esm_cause = esm_recv_deactivate_eps_bearer_context_request(pti, ebi,
+      esm_cause = esm_recv_deactivate_eps_bearer_context_request(esm_data, pti, ebi,
                   &esm_msg.deactivate_eps_bearer_context_request);
 
       if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) ||
@@ -560,7 +563,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone,
       /*
        * Process PDN connectivity reject message received from the MME
        */
-      esm_cause = esm_recv_pdn_connectivity_reject(pti, ebi,
+      esm_cause = esm_recv_pdn_connectivity_reject(esm_data, pti, ebi,
                   &esm_msg.pdn_connectivity_reject);
 
       if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) ||
@@ -583,7 +586,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone,
       /*
        * Process PDN disconnect reject message received from the MME
        */
-      esm_cause = esm_recv_pdn_disconnect_reject(pti, ebi,
+      esm_cause = esm_recv_pdn_disconnect_reject(esm_data, pti, ebi,
                   &esm_msg.pdn_disconnect_reject);
 
       if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) ||
diff --git a/openair3/NAS/UE/ESM/esmData.h b/openair3/NAS/UE/ESM/esmData.h
index 7571e25e6..24cb7b39e 100755
--- a/openair3/NAS/UE/ESM/esmData.h
+++ b/openair3/NAS/UE/ESM/esmData.h
@@ -201,7 +201,7 @@ typedef esm_data_context_t esm_data_t;
  * ESM internal data (used within ESM only)
  * ----------------------------------------
  */
-esm_data_t _esm_data;
+extern esm_data_t *_esm_data;
 
 /****************************************************************************/
 /******************  E X P O R T E D    F U N C T I O N S  ******************/
diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c
index 539403f7e..59a7fd4ec 100755
--- a/openair3/NAS/UE/ESM/esm_ebr_context.c
+++ b/openair3/NAS/UE/ESM/esm_ebr_context.c
@@ -107,7 +107,7 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *,
  **                                                                        **
  ***************************************************************************/
 int esm_ebr_context_create(
-
+  esm_data_t *esm_data,
   int pid, int ebi, int is_default,
   const network_qos_t *qos, const network_tft_t *tft)
 {
@@ -118,7 +118,7 @@ int esm_ebr_context_create(
 
   LOG_FUNC_IN;
 
-  esm_ctx = &_esm_data;
+  esm_ctx = esm_data;
 
   bid = ESM_DATA_EPS_BEARER_MAX;
 
@@ -338,7 +338,7 @@ int esm_ebr_context_create(
  **                                                                        **
  ***************************************************************************/
 int esm_ebr_context_release(
-
+  esm_data_t *esm_data,
   int ebi, int *pid, int *bid)
 {
   int found = FALSE;
@@ -349,7 +349,7 @@ int esm_ebr_context_release(
 
   LOG_FUNC_IN;
 
-  esm_ctx = &_esm_data;
+  esm_ctx = esm_data;
 
   if (ebi != ESM_EBI_UNASSIGNED) {
     /*
@@ -540,22 +540,22 @@ int esm_ebr_context_release(
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_ebr_context_get_pid(int ebi)
+int esm_ebr_context_get_pid(esm_data_t *esm_data, int ebi)
 {
   LOG_FUNC_IN;
 
   int pid;
 
   for (pid = 0; pid < ESM_DATA_PDN_MAX; pid++) {
-    if (_esm_data.pdn[pid].data == NULL) {
+    if (esm_data->pdn[pid].data == NULL) {
       continue;
     }
 
-    if (_esm_data.pdn[pid].data->bearer[0] == NULL) {
+    if (esm_data->pdn[pid].data->bearer[0] == NULL) {
       continue;
     }
 
-    if (_esm_data.pdn[pid].data->bearer[0]->ebi == ebi) {
+    if (esm_data->pdn[pid].data->bearer[0]->ebi == ebi) {
       break;
     }
   }
@@ -590,7 +590,7 @@ int esm_ebr_context_get_pid(int ebi)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_ebr_context_check_tft(int pid, int ebi,
+int esm_ebr_context_check_tft(esm_data_t *esm_data, int pid, int ebi,
                               const network_tft_t *tft,
                               esm_ebr_context_tft_t operation)
 {
@@ -600,14 +600,14 @@ int esm_ebr_context_check_tft(int pid, int ebi,
   int i;
 
   if (pid < ESM_DATA_PDN_MAX) {
-    if (pid != _esm_data.pdn[pid].pid) {
+    if (pid != esm_data->pdn[pid].pid) {
       LOG_TRACE(ERROR, "ESM-PROC  - PDN connection identifier %d "
                 "is not valid", pid);
-    } else if (_esm_data.pdn[pid].data == NULL) {
+    } else if (esm_data->pdn[pid].data == NULL) {
       LOG_TRACE(ERROR, "ESM-PROC  - PDN connection %d has not been "
                 "allocated", pid);
     } else if (operation == ESM_EBR_CONTEXT_TFT_CREATE) {
-      esm_pdn_t *pdn = _esm_data.pdn[pid].data;
+      esm_pdn_t *pdn = esm_data->pdn[pid].data;
 
       /* For each EPS bearer context associated to the PDN connection */
       for (i = 0; i < pdn->n_bearers; i++) {
diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.h b/openair3/NAS/UE/ESM/esm_ebr_context.h
index a93fb94eb..417ecbae3 100755
--- a/openair3/NAS/UE/ESM/esm_ebr_context.h
+++ b/openair3/NAS/UE/ESM/esm_ebr_context.h
@@ -72,14 +72,14 @@ typedef enum {
 /******************  E X P O R T E D    F U N C T I O N S  ******************/
 /****************************************************************************/
 
-int esm_ebr_context_create(int pid, int ebi, int is_default,
+int esm_ebr_context_create(esm_data_t *esm_data, int pid, int ebi, int is_default,
                            const network_qos_t *qos, const network_tft_t *tft);
 
-int esm_ebr_context_release(int ebi, int *pid, int *bid);
+int esm_ebr_context_release(esm_data_t *esm_data, int ebi, int *pid, int *bid);
 
-int esm_ebr_context_get_pid(int ebi);
+int esm_ebr_context_get_pid(esm_data_t *esm_data, int ebi);
 
-int esm_ebr_context_check_tft(int pid, int ebi, const network_tft_t *tft,
+int esm_ebr_context_check_tft(esm_data_t *esm_data, int pid, int ebi, const network_tft_t *tft,
                               esm_ebr_context_tft_t operation);
 
 
diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c
index f507b0a53..4bbf1ab94 100755
--- a/openair3/NAS/UE/ESM/esm_main.c
+++ b/openair3/NAS/UE/ESM/esm_main.c
@@ -57,6 +57,8 @@ Description Defines the EPS Session Management procedure call manager,
 /****************  E X T E R N A L    D E F I N I T I O N S  ****************/
 /****************************************************************************/
 
+esm_data_t *_esm_data = NULL;
+
 /****************************************************************************/
 /*******************  L O C A L    D E F I N I T I O N S  *******************/
 /****************************************************************************/
@@ -76,36 +78,42 @@ Description Defines the EPS Session Management procedure call manager,
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    None                                       **
- **      Others:    _esm_data                                  **
+ **      Others:    esm_data->                                 **
  **                                                                        **
  ***************************************************************************/
-void esm_main_initialize(esm_indication_callback_t cb)
+esm_data_t * esm_main_initialize(esm_indication_callback_t cb)
 {
   LOG_FUNC_IN;
 
   int i;
-
+  esm_data_t *esm_data = calloc(1, sizeof(esm_data_t));
+  if ( esm_data == NULL ) {
+    LOG_TRACE(ERROR, "ESM-MAIN  - Can't malloc esm_data");
+    // FIXME Stop here !!!
+  }
   /* Total number of active EPS bearer contexts */
-  _esm_data.n_ebrs = 0;
+  esm_data->n_ebrs = 0;
   /* List of active PDN connections */
-  _esm_data.n_pdns = 0;
+  esm_data->n_pdns = 0;
 
   for (i = 0; i < ESM_DATA_PDN_MAX + 1; i++) {
-    _esm_data.pdn[i].pid = -1;
-    _esm_data.pdn[i].is_active = FALSE;
-    _esm_data.pdn[i].data = NULL;
+    esm_data->pdn[i].pid = -1;
+    esm_data->pdn[i].is_active = FALSE;
+    esm_data->pdn[i].data = NULL;
   }
 
   /* Emergency bearer services indicator */
-  _esm_data.emergency = FALSE;
+  esm_data->emergency = FALSE;
 
   /* Initialize the procedure transaction identity manager */
+
   esm_pt_initialize();
 
   /* Initialize the EPS bearer context manager */
   esm_ebr_initialize(cb);
 
   LOG_FUNC_OUT;
+  return esm_data;
 }
 
 
@@ -123,7 +131,7 @@ void esm_main_initialize(esm_indication_callback_t cb)
  **                  Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-void esm_main_cleanup(void)
+void esm_main_cleanup(esm_data_t *esm_data)
 {
   LOG_FUNC_IN;
 
@@ -134,8 +142,8 @@ void esm_main_cleanup(void)
 
     /* De-activate EPS bearers and clean up PDN connections */
     for (pid = 0; pid < ESM_DATA_PDN_MAX; pid++) {
-      if (_esm_data.pdn[pid].data) {
-        esm_pdn_t *pdn = _esm_data.pdn[pid].data;
+      if (esm_data->pdn[pid].data) {
+        esm_pdn_t *pdn = esm_data->pdn[pid].data;
 
         if (pdn->apn.length > 0) {
           free(pdn->apn.value);
@@ -159,7 +167,7 @@ void esm_main_cleanup(void)
         }
 
         /* Release the PDN connection */
-        free(_esm_data.pdn[pid].data);
+        free(esm_data->pdn[pid].data);
       }
     }
   }
@@ -175,7 +183,7 @@ void esm_main_cleanup(void)
  **      a defined state at the same time                          **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _esm_data                                  **
+ **      Others:    esm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    The maximum number of PDN connections that **
@@ -183,7 +191,7 @@ void esm_main_cleanup(void)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_main_get_nb_pdns_max(void)
+int esm_main_get_nb_pdns_max(esm_data_t *esm_data)
 {
   LOG_FUNC_IN;
 
@@ -197,18 +205,18 @@ int esm_main_get_nb_pdns_max(void)
  ** Description: Get the number of active PDN connections                  **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _esm_data                                  **
+ **      Others:    esm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    The number of active PDN connections       **
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_main_get_nb_pdns(void)
+int esm_main_get_nb_pdns(esm_data_t *esm_data)
 {
   LOG_FUNC_IN;
 
-  LOG_FUNC_RETURN (_esm_data.n_pdns);
+  LOG_FUNC_RETURN (esm_data->n_pdns);
 }
 
 /****************************************************************************
@@ -219,7 +227,7 @@ int esm_main_get_nb_pdns(void)
  **      vices is established                                      **
  **                                                                        **
  ** Inputs:  None                                                      **
- **      Others:    _esm_data                                  **
+ **      Others:    esm_data->                                 **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    TRUE if a PDN connection for emergency     **
@@ -227,11 +235,11 @@ int esm_main_get_nb_pdns(void)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_main_has_emergency(void)
+int esm_main_has_emergency(esm_data_t *esm_data)
 {
   LOG_FUNC_IN;
 
-  LOG_FUNC_RETURN (_esm_data.emergency);
+  LOG_FUNC_RETURN (esm_data->emergency);
 }
 
 /****************************************************************************
@@ -241,7 +249,7 @@ int esm_main_has_emergency(void)
  ** Description: Get the status of the specified PDN connection            **
  **                                                                        **
  ** Inputs:  cid:       PDN connection identifier                  **
- **      Others:    _esm_data                                  **
+ **      Others:    esm_data->                                 **
  **                                                                        **
  ** Outputs:     state:     TRUE if the current state of the PDN con-  **
  **             nection is ACTIVE; FALSE otherwise.        **
@@ -252,7 +260,7 @@ int esm_main_has_emergency(void)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_main_get_pdn_status(int cid, int *state)
+int esm_main_get_pdn_status(esm_data_t *esm_data, int cid, int *state)
 {
   LOG_FUNC_IN;
 
@@ -260,19 +268,19 @@ int esm_main_get_pdn_status(int cid, int *state)
 
   if (pid >= ESM_DATA_PDN_MAX) {
     return (FALSE);
-  } else if (pid != _esm_data.pdn[pid].pid) {
+  } else if (pid != esm_data->pdn[pid].pid) {
     LOG_TRACE(WARNING, "ESM-MAIN  - PDN connection %d is not defined", cid);
     return (FALSE);
-  } else if (_esm_data.pdn[pid].data == NULL) {
+  } else if (esm_data->pdn[pid].data == NULL) {
     LOG_TRACE(ERROR, "ESM-MAIN  - PDN connection %d has not been allocated",
               cid);
     return (FALSE);
   }
 
-  if (_esm_data.pdn[pid].data->bearer[0] != NULL) {
+  if (esm_data->pdn[pid].data->bearer[0] != NULL) {
     /* The status of a PDN connection is the status of the default EPS bearer
      * that has been assigned to this PDN connection at activation time */
-    int ebi = _esm_data.pdn[pid].data->bearer[0]->ebi;
+    int ebi = esm_data->pdn[pid].data->bearer[0]->ebi;
     *state = (esm_ebr_get_status(ebi) == ESM_EBR_ACTIVE);
   }
 
@@ -287,7 +295,7 @@ int esm_main_get_pdn_status(int cid, int *state)
  ** Description: Get parameters defined for the specified PDN connection   **
  **                                                                        **
  ** Inputs:  cid:       PDN connection identifier                  **
- **      Others:    _esm_data                                  **
+ **      Others:    esm_data->                                 **
  **                                                                        **
  ** Outputs:     type:      PDN connection type (IPv4, IPv6, IPv4v6)   **
  **      apn:       Access Point logical Name in used          **
@@ -297,7 +305,7 @@ int esm_main_get_pdn_status(int cid, int *state)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_main_get_pdn(int cid, int *type, const char **apn,
+int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn,
                      int *is_emergency, int *is_active)
 {
   LOG_FUNC_IN;
@@ -306,29 +314,29 @@ int esm_main_get_pdn(int cid, int *type, const char **apn,
 
   if (pid >= ESM_DATA_PDN_MAX) {
     return (RETURNerror);
-  } else if (pid != _esm_data.pdn[pid].pid) {
+  } else if (pid != esm_data->pdn[pid].pid) {
     LOG_TRACE(WARNING, "ESM-MAIN  - PDN connection %d is not defined", cid);
     return (RETURNerror);
-  } else if (_esm_data.pdn[pid].data == NULL) {
+  } else if (esm_data->pdn[pid].data == NULL) {
     LOG_TRACE(ERROR, "ESM-MAIN  - PDN connection %d has not been allocated",
               cid);
     return (RETURNerror);
   }
 
   /* Get the PDN type */
-  *type = _esm_data.pdn[pid].data->type;
+  *type = esm_data->pdn[pid].data->type;
 
   /* Get the Access Point Name */
-  if (_esm_data.pdn[pid].data->apn.length > 0) {
-    *apn = (char *)(_esm_data.pdn[pid].data->apn.value);
+  if (esm_data->pdn[pid].data->apn.length > 0) {
+    *apn = (char *)(esm_data->pdn[pid].data->apn.value);
   } else {
     *apn = NULL;
   }
 
   /* Get the emergency bearer services indicator */
-  *is_emergency = _esm_data.pdn[pid].data->is_emergency;
+  *is_emergency = esm_data->pdn[pid].data->is_emergency;
   /* Get the active PDN connection indicator */
-  *is_active = _esm_data.pdn[pid].is_active;
+  *is_active = esm_data->pdn[pid].is_active;
 
   LOG_FUNC_RETURN (RETURNok);
 }
@@ -341,7 +349,7 @@ int esm_main_get_pdn(int cid, int *type, const char **apn,
  **      tion                                                      **
  **                                                                        **
  ** Inputs:  cid:       PDN connection identifier                  **
- **      Others:    _esm_data                                  **
+ **      Others:    esm_data->                                 **
  **                                                                        **
  ** Outputs:     ipv4adddr: IPv4 address                               **
  **      ipv6adddr: IPv6 address                               **
@@ -349,7 +357,7 @@ int esm_main_get_pdn(int cid, int *type, const char **apn,
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_main_get_pdn_addr(int cid, const char **ipv4addr, const char **ipv6addr)
+int esm_main_get_pdn_addr(esm_data_t *esm_data, int cid, const char **ipv4addr, const char **ipv6addr)
 {
   LOG_FUNC_IN;
 
@@ -357,35 +365,30 @@ int esm_main_get_pdn_addr(int cid, const char **ipv4addr, const char **ipv6addr)
 
   if (pid >= ESM_DATA_PDN_MAX) {
     return (RETURNerror);
-  } else if (pid != _esm_data.pdn[pid].pid) {
+  } else if (pid != esm_data->pdn[pid].pid) {
     LOG_TRACE(WARNING, "ESM-MAIN  - PDN connection %d is not defined", cid);
     return (RETURNerror);
-  } else if (_esm_data.pdn[pid].data == NULL) {
+  } else if (esm_data->pdn[pid].data == NULL) {
     LOG_TRACE(ERROR, "ESM-MAIN  - PDN connection %d has not been allocated",
               cid);
     return (RETURNerror);
-  } else if (!_esm_data.pdn[pid].is_active) {
+  } else if (!esm_data->pdn[pid].is_active) {
     /* No any IP address has been assigned to this PDN connection */
     return (RETURNok);
   }
 
-  if (_esm_data.pdn[pid].data->type == NET_PDN_TYPE_IPV4) {
+  if (esm_data->pdn[pid].data->type == NET_PDN_TYPE_IPV4) {
     /* Get IPv4 address */
-    *ipv4addr = _esm_data.pdn[pid].data->ip_addr;
-  } else if (_esm_data.pdn[pid].data->type == NET_PDN_TYPE_IPV6) {
+    *ipv4addr = esm_data->pdn[pid].data->ip_addr;
+  } else if (esm_data->pdn[pid].data->type == NET_PDN_TYPE_IPV6) {
     /* Get IPv6 address */
-    *ipv6addr = _esm_data.pdn[pid].data->ip_addr;
+    *ipv6addr = esm_data->pdn[pid].data->ip_addr;
   } else {
     /* IPv4v6 dual-stack terminal */
-    *ipv4addr = _esm_data.pdn[pid].data->ip_addr;
-    *ipv6addr = _esm_data.pdn[pid].data->ip_addr+ESM_DATA_IPV4_ADDRESS_SIZE;
+    *ipv4addr = esm_data->pdn[pid].data->ip_addr;
+    *ipv6addr = esm_data->pdn[pid].data->ip_addr+ESM_DATA_IPV4_ADDRESS_SIZE;
   }
 
   LOG_FUNC_RETURN (RETURNok);
 }
 
-
-/****************************************************************************/
-/*********************  L O C A L    F U N C T I O N S  *********************/
-/****************************************************************************/
-
diff --git a/openair3/NAS/UE/ESM/esm_main.h b/openair3/NAS/UE/ESM/esm_main.h
index 9fe1e598c..2b0f69a52 100755
--- a/openair3/NAS/UE/ESM/esm_main.h
+++ b/openair3/NAS/UE/ESM/esm_main.h
@@ -49,6 +49,7 @@ Description Defines the EPS Session Management procedure call manager,
 
 #include "networkDef.h"
 #include "esm_ebr.h"
+#include "esmData.h"
 
 /****************************************************************************/
 /*********************  G L O B A L    C O N S T A N T S  *******************/
@@ -66,19 +67,19 @@ Description Defines the EPS Session Management procedure call manager,
 /******************  E X P O R T E D    F U N C T I O N S  ******************/
 /****************************************************************************/
 
-void esm_main_initialize(esm_indication_callback_t cb);
+esm_data_t * esm_main_initialize(esm_indication_callback_t cb);
 
-void esm_main_cleanup(void);
+void esm_main_cleanup(esm_data_t *esm_data);
 
 
 /* User's getter for PDN connections and EPS bearer contexts */
-int esm_main_get_nb_pdns_max(void);
-int esm_main_get_nb_pdns(void);
-int esm_main_has_emergency(void);
-int esm_main_get_pdn_status(int cid, int *state);
-int esm_main_get_pdn(int cid, int *type, const char **apn, int *is_emergency,
+int esm_main_get_nb_pdns_max(esm_data_t *esm_data);
+int esm_main_get_nb_pdns(esm_data_t *esm_data);
+int esm_main_has_emergency(esm_data_t *esm_data);
+int esm_main_get_pdn_status(esm_data_t *esm_data, int cid, int *state);
+int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, int *is_emergency,
                      int *is_active);
-int esm_main_get_pdn_addr(int cid, const char **ipv4addr, const char **ipv6addr);
+int esm_main_get_pdn_addr(esm_data_t *esm_data, int cid, const char **ipv4addr, const char **ipv6addr);
 
 
 #endif /* __ESM_MAIN_H__*/
diff --git a/openair3/NAS/UE/ESM/esm_proc.h b/openair3/NAS/UE/ESM/esm_proc.h
index 094907257..49d568a57 100755
--- a/openair3/NAS/UE/ESM/esm_proc.h
+++ b/openair3/NAS/UE/ESM/esm_proc.h
@@ -128,12 +128,12 @@ int esm_proc_status(int is_standalone, int pti, OctetString *msg,
  *          PDN connectivity procedure
  * --------------------------------------------------------------------------
  */
-int esm_proc_pdn_connectivity(int cid, int to_define,
+int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int to_define,
                               esm_proc_pdn_type_t pdn_type, const OctetString *apn, int is_emergency,
                               unsigned int *pti);
 int esm_proc_pdn_connectivity_request(int is_standalone, int pti,
                                       OctetString *msg, int sent_by_ue);
-int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type,
+int esm_proc_pdn_connectivity_accept(esm_data_t *esm_data, int pti, esm_proc_pdn_type_t pdn_type,
                                      const OctetString *pdn_address, const OctetString *apn, int *esm_cause);
 int esm_proc_pdn_connectivity_reject(int pti, int *esm_cause);
 int esm_proc_pdn_connectivity_complete(void);
@@ -145,12 +145,12 @@ int esm_proc_pdn_connectivity_failure(int is_pending);
  *              PDN disconnect procedure
  * --------------------------------------------------------------------------
  */
-int esm_proc_pdn_disconnect(int cid, unsigned int *pti, unsigned int *ebi);
+int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, unsigned int *ebi);
 int esm_proc_pdn_disconnect_request(int is_standalone, int pti,
                                     OctetString *msg, int sent_by_ue);
 
 int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause);
-int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause);
+int esm_proc_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int *esm_cause);
 
 /*
  * --------------------------------------------------------------------------
@@ -158,10 +158,10 @@ int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause);
  * --------------------------------------------------------------------------
  */
 
-int esm_proc_default_eps_bearer_context_request(int pid, int ebi,
+int esm_proc_default_eps_bearer_context_request(esm_data_t *esm_data, int pid, int ebi,
     const esm_proc_qos_t *esm_qos, int *esm_cause);
 int esm_proc_default_eps_bearer_context_complete(void);
-int esm_proc_default_eps_bearer_context_failure(void);
+int esm_proc_default_eps_bearer_context_failure(esm_data_t *esm_data);
 
 int esm_proc_default_eps_bearer_context_accept(int is_standalone, int ebi,
     OctetString *msg, int ue_triggered);
@@ -174,7 +174,7 @@ int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi,
  * --------------------------------------------------------------------------
  */
 
-int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi,
+int esm_proc_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int ebi, int default_ebi,
     const esm_proc_qos_t *qos, const esm_proc_tft_t *tft, int *esm_cause);
 
 int esm_proc_dedicated_eps_bearer_context_accept(int is_standalone, int ebi,
@@ -188,9 +188,9 @@ int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi,
  * --------------------------------------------------------------------------
  */
 
-int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi, int *pid,
+int esm_proc_eps_bearer_context_deactivate(esm_data_t *esm_data, int is_local, int ebi, int *pid,
     int *bid);
-int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause);
+int esm_proc_eps_bearer_context_deactivate_request(esm_data_t *esm_data, int ebi, int *esm_cause);
 
 int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi,
     OctetString *msg, int ue_triggered);
diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c
index bc38c03de..4ed56c4d2 100644
--- a/openair3/NAS/UE/nas_proc.c
+++ b/openair3/NAS/UE/nas_proc.c
@@ -108,7 +108,7 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb,
   emm_main_initialize(emm_cb, imei);
 
   /* Initialize the ESM procedure manager */
-  esm_main_initialize(esm_cb);
+  _esm_data = esm_main_initialize(esm_cb);
 
   LOG_FUNC_OUT;
 }
@@ -144,7 +144,7 @@ void nas_proc_cleanup(nas_user_t *user)
   emm_main_cleanup();
 
   /* Perform the EPS Session Manager's clean up procedure */
-  esm_main_cleanup();
+  esm_main_cleanup(_esm_data);
 
   LOG_FUNC_OUT;
 }
@@ -656,11 +656,11 @@ int nas_proc_get_attach_status(nas_user_t *user)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int nas_proc_get_pdn_range(nas_user_t *user)
+int nas_proc_get_pdn_range(esm_data_t *esm_data)
 {
   LOG_FUNC_IN;
 
-  int max_pdn_id = esm_main_get_nb_pdns_max();
+  int max_pdn_id = esm_main_get_nb_pdns_max(esm_data);
 
   LOG_FUNC_RETURN (max_pdn_id);
 }
@@ -681,7 +681,7 @@ int nas_proc_get_pdn_range(nas_user_t *user)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_max)
+int nas_proc_get_pdn_status(esm_data_t *esm_data, int *cids, int *states, int n_pdn_max)
 {
   LOG_FUNC_IN;
 
@@ -689,13 +689,13 @@ int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_
   int n_defined_pdn = 0;
 
   /* Get the maximum number of supported PDN contexts */
-  int n_pdn = esm_main_get_nb_pdns_max();
+  int n_pdn = esm_main_get_nb_pdns_max(esm_data);
 
   /* For all PDN contexts */
   for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) {
     /* Get the status of this PDN */
     int state = FALSE;
-    int is_defined = esm_main_get_pdn_status(cid, &state);
+    int is_defined = esm_main_get_pdn_status(esm_data, cid, &state);
 
     if (is_defined != FALSE) {
       /* This PDN has been defined */
@@ -725,7 +725,7 @@ int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int nas_proc_get_pdn_param(nas_user_t *user, int *cids, int *types, const char **apns,
+int nas_proc_get_pdn_param(esm_data_t *esm_data, int *cids, int *types, const char **apns,
                            int n_pdn_max)
 {
   LOG_FUNC_IN;
@@ -734,13 +734,13 @@ int nas_proc_get_pdn_param(nas_user_t *user, int *cids, int *types, const char *
   int n_defined_pdn = 0;
 
   /* Get the maximum number of supported PDN contexts */
-  int n_pdn = esm_main_get_nb_pdns_max();
+  int n_pdn = esm_main_get_nb_pdns_max(esm_data);
 
   /* For all PDN contexts */
   for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) {
     int emergency, active;
     /* Get PDN connection parameters */
-    int rc = esm_main_get_pdn(cid, types, apns, &emergency, &active);
+    int rc = esm_main_get_pdn(esm_data, cid, types, apns, &emergency, &active);
 
     if (rc != RETURNerror) {
       /* This PDN has been defined */
@@ -787,7 +787,7 @@ int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **add
 
   if (cid > 0) {
     /* Get addresses assigned to the specified PDN */
-    rc = esm_main_get_pdn_addr(cid, addr1, addr2);
+    rc = esm_main_get_pdn_addr(_esm_data, cid, addr1, addr2);
 
     if (rc != RETURNerror) {
       *cids = cid;
@@ -795,12 +795,12 @@ int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **add
     }
   } else if (cid < 0) {
     /* Get the maximum number of supported PDN contexts */
-    int n_pdn = esm_main_get_nb_pdns_max();
+    int n_pdn = esm_main_get_nb_pdns_max(_esm_data);
 
     /* For all PDN contexts */
     for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) {
       /* Get PDN connection addresses */
-      rc = esm_main_get_pdn_addr(cid, addr1, addr2);
+      rc = esm_main_get_pdn_addr(_esm_data, cid, addr1, addr2);
 
       if (rc != RETURNerror) {
         /* This PDN has been defined */
@@ -927,7 +927,7 @@ int nas_proc_deactivate_pdn(nas_user_t *user, int cid)
     cid = 2;
 
     /* Deactivate all active PDN contexts */
-    while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max()+1)) {
+    while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(_esm_data)+1)) {
       rc = _nas_proc_deactivate(user, cid++, TRUE);
     }
   }
@@ -979,7 +979,7 @@ int nas_proc_activate_pdn(nas_user_t *user, int cid)
       cid = 1;
 
       /* Activate all defined PDN contexts */
-      while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max()+1)) {
+      while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(_esm_data)+1)) {
         rc = _nas_proc_activate(user, cid++, TRUE);
       }
     }
@@ -1298,7 +1298,7 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all)
   esm_sap_t esm_sap;
 
   /* Get PDN context parameters */
-  rc = esm_main_get_pdn(cid, &esm_sap.data.pdn_connect.pdn_type,
+  rc = esm_main_get_pdn(_esm_data, cid, &esm_sap.data.pdn_connect.pdn_type,
                         &esm_sap.data.pdn_connect.apn,
                         &esm_sap.data.pdn_connect.is_emergency, &active);
 
@@ -1320,7 +1320,7 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all)
   }
 
   if (esm_sap.data.pdn_connect.is_emergency) {
-    if (esm_main_has_emergency()) {
+    if (esm_main_has_emergency(_esm_data)) {
       /* There is already a PDN connection for emergency
        * bearer services established; the UE shall not
        * request an additional PDN connection for emer-
@@ -1372,7 +1372,7 @@ static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all)
   int active = FALSE;
 
   /* Get PDN context parameters */
-  rc = esm_main_get_pdn(cid, &pdn_type, &apn, &emergency, &active);
+  rc = esm_main_get_pdn(_esm_data, cid, &pdn_type, &apn, &emergency, &active);
 
   if (rc != RETURNok) {
     /* No any context is defined for the specified PDN */
@@ -1390,7 +1390,7 @@ static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all)
     LOG_FUNC_RETURN (RETURNok);
   }
 
-  if (esm_main_get_nb_pdns() > 1) {
+  if (esm_main_get_nb_pdns(_esm_data) > 1) {
     /*
      * Notify ESM that all EPS bearers towards the specified PDN
      * has to be released
diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h
index 8dad4b62a..a2708a1ea 100755
--- a/openair3/NAS/UE/nas_proc.h
+++ b/openair3/NAS/UE/nas_proc.h
@@ -50,6 +50,7 @@ Description NAS procedure call manager
 #include "user_defs.h"
 #include "emm_main.h"
 #include "esm_ebr.h"
+#include "esmData.h"
 
 /****************************************************************************/
 /*********************  G L O B A L    C O N S T A N T S  *******************/
@@ -103,9 +104,9 @@ int nas_proc_get_attach_status(nas_user_t *user);
 int nas_proc_reset_pdn(nas_user_t *user, int cid);
 int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int ipv4_addr,
                      int emergency, int p_cscf, int im_cn_signal);
-int nas_proc_get_pdn_range(nas_user_t *user);
-int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_max);
-int nas_proc_get_pdn_param(nas_user_t *user, int *cids, int *types, const char **apns,
+int nas_proc_get_pdn_range(esm_data_t *esm_data);
+int nas_proc_get_pdn_status(esm_data_t *esm_data, int *cids, int *states, int n_pdn_max);
+int nas_proc_get_pdn_param(esm_data_t *esm_data, int *cids, int *types, const char **apns,
                            int n_pdn_max);
 int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **addr1,
                           const char **addr2, int n_addr_max);
diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c
index 966b7bfe4..49b2d87f5 100644
--- a/openair3/NAS/UE/nas_user.c
+++ b/openair3/NAS/UE/nas_user.c
@@ -2050,7 +2050,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data)
      * Read command returns the current settings for each
      * defined PDN connection/default EPS bearer context
      */
-    cgdcont->n_pdns = nas_proc_get_pdn_param(user, cgdcont->cid,
+    cgdcont->n_pdns = nas_proc_get_pdn_param(_esm_data, cgdcont->cid,
                       cgdcont->PDP_type,
                       cgdcont->APN,
                       AT_CGDCONT_RESP_SIZE);
@@ -2068,7 +2068,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data)
      */
   {
     /* Get the maximum value of a PDN context identifier */
-    int cid_max = nas_proc_get_pdn_range(user);
+    int cid_max = nas_proc_get_pdn_range(_esm_data);
 
     if (cid_max > AT_CGDCONT_RESP_SIZE) {
       /* The range is defined by the user interface */
@@ -2191,7 +2191,7 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data)
      * The read command returns the current activation states for
      * all the defined PDN/EPS bearer contexts
      */
-    cgact->n_pdns = nas_proc_get_pdn_status(user, cgact->cid, cgact->state,
+    cgact->n_pdns = nas_proc_get_pdn_status(_esm_data, cgact->cid, cgact->state,
                                             AT_CGACT_RESP_SIZE);
 
     if (cgact->n_pdns == 0) {
-- 
GitLab