From 809be889a73b630b720fec99a88f805355bae25c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= <frederic.leroy@b-com.com>
Date: Tue, 12 Jul 2016 15:03:12 +0200
Subject: [PATCH] UE/ESM: move _esm_ebr_data to nas_user_t

---
 .../ESM/DedicatedEpsBearerContextActivation.c |  10 +-
 .../ESM/DefaultEpsBearerContextActivation.c   |  11 +-
 .../NAS/UE/ESM/EpsBearerContextDeactivation.c |  10 +-
 openair3/NAS/UE/ESM/SAP/esm_recv.c            |  14 +--
 openair3/NAS/UE/ESM/esm_ebr.c                 | 115 ++++++++----------
 openair3/NAS/UE/ESM/esm_ebr.h                 |  17 +--
 openair3/NAS/UE/ESM/esm_ebr_context.c         |  11 +-
 openair3/NAS/UE/ESM/esm_main.c                |  11 +-
 openair3/NAS/UE/ESM/esm_main.h                |   2 +-
 openair3/NAS/UE/nas_proc.c                    |   6 +-
 openair3/NAS/UE/nas_proc.h                    |   2 +-
 openair3/NAS/UE/nas_user.c                    |   2 +-
 openair3/NAS/UE/user_defs.h                   |   1 +
 13 files changed, 100 insertions(+), 112 deletions(-)

diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c
index 55008d7dac7..c96a40a1b8e 100644
--- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c
+++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c
@@ -131,7 +131,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int
   }
 
   /* Assign dedicated EPS bearer context */
-  int new_ebi = esm_ebr_assign(ebi, pid+1, FALSE);
+  int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, FALSE);
 
   if (new_ebi == ESM_EBI_UNASSIGNED) {
     /* 3GPP TS 24.301, section 6.4.2.5, abnormal cases a and b
@@ -149,7 +149,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int
       *esm_cause = ESM_CAUSE_PROTOCOL_ERROR;
     } else {
       /* Assign new dedicated EPS bearer context */
-      ebi = esm_ebr_assign(ebi, pid+1, FALSE);
+      ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, FALSE);
     }
   }
 
@@ -229,7 +229,7 @@ int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standa
 
   if (rc != RETURNerror) {
     /* Set the EPS bearer context state to ACTIVE */
-    rc = esm_ebr_set_status(ebi, ESM_EBR_ACTIVE, ue_triggered);
+    rc = esm_ebr_set_status(user->esm_ebr_data, ebi, ESM_EBR_ACTIVE, ue_triggered);
 
     if (rc != RETURNok) {
       /* The EPS bearer context was already in ACTIVE state */
@@ -276,9 +276,9 @@ int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standa
   LOG_TRACE(WARNING, "ESM-PROC  - Dedicated EPS bearer context activation "
             "not accepted by the UE (ebi=%d)", ebi);
 
-  if ( !esm_ebr_is_not_in_use(ebi) ) {
+  if ( !esm_ebr_is_not_in_use(user->esm_ebr_data, ebi) ) {
     /* Release EPS bearer data currently in use */
-    rc = esm_ebr_release(ebi);
+    rc = esm_ebr_release(user->esm_ebr_data, ebi);
   }
 
   if (rc != RETURNok) {
diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c
index a5e70703ed4..68d1ce8eab1 100644
--- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c
+++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c
@@ -116,7 +116,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e
             "requested by the network (ebi=%d)", ebi);
 
   /* Assign default EPS bearer context */
-  int new_ebi = esm_ebr_assign(ebi, pid+1, TRUE);
+  int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, TRUE);
 
   if (new_ebi == ESM_EBI_UNASSIGNED) {
     /* 3GPP TS 24.301, section 6.4.1.5, abnormal cases a and b
@@ -134,7 +134,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e
       *esm_cause = ESM_CAUSE_PROTOCOL_ERROR;
     } else {
       /* Assign new default EPS bearer context */
-      ebi = esm_ebr_assign(ebi, pid+1, TRUE);
+      ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, TRUE);
     }
   }
 
@@ -213,7 +213,7 @@ int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalo
 
   if (rc != RETURNerror) {
     /* Set the EPS bearer context state to ACTIVE */
-    rc = esm_ebr_set_status(ebi, ESM_EBR_ACTIVE, ue_triggered);
+    rc = esm_ebr_set_status(user->esm_ebr_data, ebi, ESM_EBR_ACTIVE, ue_triggered);
 
     if (rc != RETURNok) {
       /* The EPS bearer context was already in ACTIVE state */
@@ -266,9 +266,9 @@ int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalo
   LOG_TRACE(WARNING, "ESM-PROC  - Default EPS bearer context activation "
             "not accepted by the UE (ebi=%d)", ebi);
 
-  if ( !esm_ebr_is_not_in_use(ebi) ) {
+  if ( !esm_ebr_is_not_in_use(user->esm_ebr_data, ebi) ) {
     /* Release EPS bearer data currently in use */
-    rc = esm_ebr_release(ebi);
+    rc = esm_ebr_release(user->esm_ebr_data, ebi);
   }
 
   if (rc != RETURNok) {
@@ -280,6 +280,7 @@ int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalo
      * Notity EMM that ESM PDU has to be forwarded to lower layers
      */
     emm_sap.primitive = EMMESM_UNITDATA_REQ;
+    // FIXME REVIEW
     emm_sap.u.emm_esm.ueid = 0;
     emm_esm->msg.length = msg->length;
     emm_esm->msg.value = msg->value;
diff --git a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c
index fdba605f1e0..c92ce2c5829 100644
--- a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c
+++ b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c
@@ -281,6 +281,7 @@ int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_stand
   LOG_FUNC_IN;
 
   int rc = RETURNok;
+  esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data;
 
   LOG_TRACE(INFO,"ESM-PROC  - EPS bearer context deactivation accepted");
 
@@ -298,7 +299,7 @@ int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_stand
 
   if (rc != RETURNerror) {
     /* Set the EPS bearer context state to INACTIVE */
-    rc = esm_ebr_set_status(ebi, ESM_EBR_INACTIVE, ue_triggered);
+    rc = esm_ebr_set_status(esm_ebr_data, ebi, ESM_EBR_INACTIVE, ue_triggered);
 
     if (rc != RETURNok) {
       /* The EPS bearer context was already in INACTIVE state */
@@ -309,7 +310,7 @@ int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_stand
     }
 
     /* Release EPS bearer data */
-    rc = esm_ebr_release(ebi);
+    rc = esm_ebr_release(esm_ebr_data, ebi);
   }
 
   LOG_FUNC_RETURN (rc);
@@ -357,6 +358,7 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid)
   LOG_FUNC_IN;
 
   int rc = RETURNerror;
+  esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data;
 
   /* Release the EPS bearer context entry */
   ebi = esm_ebr_context_release(user, ebi, pid, bid);
@@ -365,14 +367,14 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid)
     LOG_TRACE(WARNING, "ESM-PROC  - Failed to release EPS bearer context");
   } else {
     /* Set the EPS bearer context state to INACTIVE */
-    rc = esm_ebr_set_status(ebi, ESM_EBR_INACTIVE, FALSE);
+    rc = esm_ebr_set_status(esm_ebr_data, ebi, ESM_EBR_INACTIVE, FALSE);
 
     if (rc != RETURNok) {
       /* The EPS bearer context was already in INACTIVE state */
       LOG_TRACE(WARNING, "ESM-PROC  - EBI %d was already INACTIVE", ebi);
     } else {
       /* Release EPS bearer data */
-      rc = esm_ebr_release(ebi);
+      rc = esm_ebr_release(esm_ebr_data, ebi);
 
       if (rc != RETURNok) {
         LOG_TRACE(WARNING,
diff --git a/openair3/NAS/UE/ESM/SAP/esm_recv.c b/openair3/NAS/UE/ESM/SAP/esm_recv.c
index ba8fafaf1ce..03a42155811 100644
--- a/openair3/NAS/UE/ESM/SAP/esm_recv.c
+++ b/openair3/NAS/UE/ESM/SAP/esm_recv.c
@@ -74,7 +74,7 @@ Description Defines functions executed at the ESM Service Access
  **                                                                        **
  ** Description: Processes ESM status message                              **
  **                                                                        **
- ** Inputs:  ueid:      UE local identifier                        **
+ ** Inputs:  **
  **      pti:       Procedure transaction identity             **
  **      ebi:       EPS bearer identity                        **
  **      msg:       The received ESM message                   **
@@ -164,7 +164,7 @@ int esm_recv_pdn_connectivity_reject(nas_user_t *user, int pti, int ebi,
   /*
    * EPS bearer identity checking
    */
-  else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) {
+  else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) {
     /* 3GPP TS 24.301, section 7.3.2, case a
      * Assigned or reserved EPS bearer identity value */
     LOG_TRACE(WARNING, "ESM-SAP   - Invalid EPS bearer identity (ebi=%d)",
@@ -235,7 +235,7 @@ int esm_recv_pdn_disconnect_reject(nas_user_t *user, int pti, int ebi,
   /*
    * EPS bearer identity checking
    */
-  else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) {
+  else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) {
     /* 3GPP TS 24.301, section 7.3.2, case b
      * Assigned or reserved EPS bearer identity value */
     LOG_TRACE(WARNING, "ESM-SAP   - Invalid EPS bearer identity (ebi=%d)",
@@ -308,7 +308,7 @@ int esm_recv_activate_default_eps_bearer_context_request(nas_user_t *user, int p
   /*
    * EPS bearer identity checking
    */
-  else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) {
+  else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) {
     /* 3GPP TS 24.301, section 7.3.2, case g
      * Reserved or unassigned EPS bearer identity value
      */
@@ -439,7 +439,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(nas_user_t *user, int
   /*
    * EPS bearer identity checking
    */
-  else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) {
+  else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) {
     /* 3GPP TS 24.301, section 7.3.2, case h
      * Reserved or unassigned EPS bearer identity value
      */
@@ -647,8 +647,8 @@ int esm_recv_deactivate_eps_bearer_context_request(nas_user_t *user, int pti, in
   /*
    * EPS bearer identity checking
    */
-  else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ||
-            esm_ebr_is_not_in_use(ebi) ) {
+  else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ||
+            esm_ebr_is_not_in_use(user->esm_ebr_data, ebi) ) {
     /* 3GPP TS 24.301, section 7.3.2, case j
      * Reserved or unassigned EPS bearer identity value or,
      * assigned value that does not match an existing EPS bearer context
diff --git a/openair3/NAS/UE/ESM/esm_ebr.c b/openair3/NAS/UE/ESM/esm_ebr.c
index 57b168930d7..81d3ff3270b 100644
--- a/openair3/NAS/UE/ESM/esm_ebr.c
+++ b/openair3/NAS/UE/ESM/esm_ebr.c
@@ -50,9 +50,6 @@ Description Defines functions used to handle state of EPS bearer contexts
 /****************  E X T E R N A L    D E F I N I T I O N S  ****************/
 /****************************************************************************/
 
-#define ESM_EBR_NB_UE_MAX   1
-
-
 /****************************************************************************/
 /*******************  L O C A L    D E F I N I T I O N S  *******************/
 /****************************************************************************/
@@ -63,14 +60,6 @@ static const char *_esm_ebr_state_str[ESM_EBR_STATE_MAX] = {
   "BEARER CONTEXT ACTIVE",
 };
 
-/*
- * ----------------------------------
- * List of EPS bearer contexts per UE
- * ----------------------------------
- */
-
-static esm_ebr_data_t _esm_ebr_data[ESM_EBR_NB_UE_MAX];
-
 /*
  * ----------------------
  * User notification data
@@ -100,7 +89,7 @@ static const network_pdn_state_t _esm_ebr_pdn_state[2][2][2] = {
 /* Returns the index of the next available entry in the list of EPS bearer
  * context data */
 
-static int _esm_ebr_get_available_entry(unsigned int ueid);
+static int _esm_ebr_get_available_entry(esm_ebr_data_t *esm_ebr_data);
 
 /****************************************************************************/
 /******************  E X P O R T E D    F U N C T I O N S  ******************/
@@ -117,39 +106,51 @@ static int _esm_ebr_get_available_entry(unsigned int ueid);
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    None                                       **
- **      Others:    _esm_ebr_data                              **
  **                                                                        **
  ***************************************************************************/
-void esm_ebr_initialize(
-  esm_indication_callback_t cb
-)
+
+esm_ebr_data_t *esm_ebr_initialize(void)
 {
-  int ueid, i;
 
   LOG_FUNC_IN;
 
-  for (ueid = 0; ueid < ESM_EBR_NB_UE_MAX; ueid++) {
-    _esm_ebr_data[ueid].index = 0;
+  int i;
+  esm_ebr_data_t *esm_ebr_data = calloc(1, sizeof(esm_ebr_data_t));
 
-    /* Initialize EPS bearer context data */
-    for (i = 0; i < ESM_EBR_DATA_SIZE + 1; i++) {
-      _esm_ebr_data[ueid].context[i] = NULL;
-    }
+  if ( esm_ebr_data == NULL ) {
+    LOG_TRACE(ERROR, "ESM-EBR  - Can't malloc esm_ebr_data");
+    // FIXME Stop here !!!
+  }
+
+  esm_ebr_data->index = 0;
+
+  /* Initialize EPS bearer context data */
+  for (i = 0; i < ESM_EBR_DATA_SIZE + 1; i++) {
+    esm_ebr_data->context[i] = NULL;
   }
 
+  LOG_FUNC_OUT;
+  return esm_ebr_data;
+}
+
+void esm_ebr_register_callback(esm_indication_callback_t cb)
+{
+
+  LOG_FUNC_IN;
+
   /* Initialize the user notification callback */
   _esm_ebr_callback = *cb;
 
   LOG_FUNC_OUT;
 }
 
+
 /****************************************************************************
  **                                                                        **
  ** Name:    esm_ebr_assign()                                          **
  **                                                                        **
  ** Description: Assigns a new EPS bearer context                          **
  **                                                                        **
- ** Inputs:  ueid:      Lower layers UE identifier                 **
  **      ebi:       Identity of the new EPS bearer context     **
  **      cid:       Identifier of the PDN context the EPS bea- **
  **             rer context is associated to               **
@@ -161,18 +162,16 @@ void esm_ebr_initialize(
  **      Return:    The identity of the new EPS bearer context **
  **             if successfully assigned;                  **
  **             the not assigned EBI (0) otherwise.        **
- **      Others:    _esm_ebr_data                              **
  **                                                                        **
  ***************************************************************************/
-int esm_ebr_assign(int ebi, int cid, int default_ebr)
+int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, int default_ebr)
 {
   esm_ebr_context_t *ebr_ctx = NULL;
-  unsigned int       ueid    = 0;
   int                i;
 
   LOG_FUNC_IN;
 
-  ebr_ctx = _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN];
+  ebr_ctx = esm_ebr_data->context[ebi - ESM_EBI_MIN];
 
 
   if (ebi != ESM_EBI_UNASSIGNED) {
@@ -188,7 +187,7 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr)
     i = ebi - ESM_EBI_MIN;
   } else {
     /* Search for an available EPS bearer identity */
-    i = _esm_ebr_get_available_entry(ueid);
+    i = _esm_ebr_get_available_entry(esm_ebr_data);
 
     if (i < 0) {
       LOG_FUNC_RETURN(ESM_EBI_UNASSIGNED);
@@ -207,10 +206,10 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr)
   }
 
 
-  _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN] = ebr_ctx;
+  esm_ebr_data->context[ebi - ESM_EBI_MIN] = ebr_ctx;
 
   /* Store the index of the next available EPS bearer identity */
-  _esm_ebr_data[ueid].index = i + 1;
+  esm_ebr_data->index = i + 1;
 
   /* Set the EPS bearer identity */
   ebr_ctx->ebi = ebi;
@@ -231,7 +230,7 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr)
  **                                                                        **
  ** Description: Release the given EPS bearer identity                     **
  **                                                                        **
- ** Inputs:  ueid:      Lower layers UE identifier                 **
+ ** Inputs:   **
  **      ebi:       The identity of the EPS bearer context to  **
  **             be released                                **
  **      Others:    None                                       **
@@ -240,13 +239,11 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr)
  **      Return:    RETURNok if the EPS bearer context has     **
  **             been successfully released;                **
  **             RETURNerror otherwise.                     **
- **      Others:    _esm_ebr_data                              **
  **                                                                        **
  ***************************************************************************/
-int esm_ebr_release(
+int esm_ebr_release(esm_ebr_data_t *esm_ebr_data,
   int ebi)
 {
-  unsigned int ueid = 0;
   esm_ebr_context_t *ebr_ctx;
 
   LOG_FUNC_IN;
@@ -256,7 +253,7 @@ int esm_ebr_release(
   }
 
   /* Get EPS bearer context data */
-  ebr_ctx = _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN];
+  ebr_ctx = esm_ebr_data->context[ebi - ESM_EBI_MIN];
 
   if ( (ebr_ctx == NULL) || (ebr_ctx->ebi != ebi) ) {
     /* EPS bearer context not assigned */
@@ -286,7 +283,6 @@ int esm_ebr_release(
  ** Description: Set the status of the specified EPS bearer context to the **
  **      given state                                               **
  **                                                                        **
- ** Inputs:  ueid:      Lower layers UE identifier                 **
  **      ebi:       The identity of the EPS bearer             **
  **      status:    The new EPS bearer context status          **
  **      ue_requested:  TRUE/FALSE if the modification of the EPS  **
@@ -296,10 +292,9 @@ int esm_ebr_release(
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    RETURNok, RETURNerror                      **
- **      Others:    _esm_ebr_data                              **
  **                                                                        **
  ***************************************************************************/
-int esm_ebr_set_status(
+int esm_ebr_set_status(esm_ebr_data_t *esm_ebr_data,
   int ebi, esm_ebr_state status, int ue_requested)
 {
   esm_ebr_context_t *ebr_ctx;
@@ -307,19 +302,13 @@ int esm_ebr_set_status(
 
   LOG_FUNC_IN;
 
-  unsigned int ueid = 0;
-
-  if (ueid >= ESM_EBR_NB_UE_MAX) {
-    LOG_FUNC_RETURN (RETURNerror);
-  }
-
 
   if ( (ebi < ESM_EBI_MIN) || (ebi > ESM_EBI_MAX) ) {
     LOG_FUNC_RETURN (RETURNerror);
   }
 
   /* Get EPS bearer context data */
-  ebr_ctx = _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN];
+  ebr_ctx = esm_ebr_data->context[ebi - ESM_EBI_MIN];
 
   if ( (ebr_ctx == NULL) || (ebr_ctx->ebi != ebi) ) {
     /* EPS bearer context not assigned */
@@ -356,9 +345,7 @@ int esm_ebr_set_status(
  ** Description: Get the current status value of the specified EPS bearer  **
  **      context                                                   **
  **                                                                        **
- ** Inputs:  ueid:      Lower layers UE identifier                 **
  **      ebi:       The identity of the EPS bearer             **
- **      Others:    _esm_ebr_data                              **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    The current value of the EPS bearer con-   **
@@ -367,26 +354,25 @@ int esm_ebr_set_status(
  **                                                                        **
  ***************************************************************************/
 
-esm_ebr_state esm_ebr_get_status(
+esm_ebr_state esm_ebr_get_status(esm_ebr_data_t *esm_ebr_data,
   int ebi)
 {
-  unsigned int ueid = 0;
 
   if ( (ebi < ESM_EBI_MIN) || (ebi > ESM_EBI_MAX) ) {
     return (ESM_EBR_INACTIVE);
   }
 
-  if (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN] == NULL) {
+  if (esm_ebr_data->context[ebi - ESM_EBI_MIN] == NULL) {
     /* EPS bearer context not allocated */
     return (ESM_EBR_INACTIVE);
   }
 
-  if (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]->ebi != ebi) {
+  if (esm_ebr_data->context[ebi - ESM_EBI_MIN]->ebi != ebi) {
     /* EPS bearer context not assigned */
     return (ESM_EBR_INACTIVE);
   }
 
-  return (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]->status);
+  return (esm_ebr_data->context[ebi - ESM_EBI_MIN]->status);
 }
 
 /****************************************************************************
@@ -404,7 +390,7 @@ esm_ebr_state esm_ebr_get_status(
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_ebr_is_reserved(int ebi)
+int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi)
 {
   return ( (ebi != ESM_EBI_UNASSIGNED) && (ebi < ESM_EBI_MIN) );
 }
@@ -416,23 +402,20 @@ int esm_ebr_is_reserved(int ebi)
  ** Description: Check whether the given EPS bearer identity does not      **
  **      match an assigned EBI value currently in use              **
  **                                                                        **
- ** Inputs:  ueid:      Lower layers UE identifier                 **
  **      ebi:       The identity of the EPS bearer             **
- **      Others:    _esm_ebr_data                              **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    TRUE, FALSE                                **
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_ebr_is_not_in_use(
+int esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data,
   int ebi)
 {
-  unsigned int ueid = 0;
 
   return ( (ebi == ESM_EBI_UNASSIGNED) ||
-           (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN] == NULL) ||
-           (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]->ebi) != ebi);
+           (esm_ebr_data->context[ebi - ESM_EBI_MIN] == NULL) ||
+           (esm_ebr_data->context[ebi - ESM_EBI_MIN]->ebi) != ebi);
 }
 
 /****************************************************************************/
@@ -446,8 +429,6 @@ int esm_ebr_is_not_in_use(
  ** Description: Returns the index of the next available entry in the list **
  **      of EPS bearer context data                                **
  **                                                                        **
- ** Inputs:  ueid:      Lower layers UE identifier                 **
- **      Others:    _esm_ebr_data                              **
  **                                                                        **
  ** Outputs:     None                                                      **
  **      Return:    The index of the next available EPS bearer **
@@ -456,20 +437,20 @@ int esm_ebr_is_not_in_use(
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _esm_ebr_get_available_entry(unsigned int ueid)
+static int _esm_ebr_get_available_entry(esm_ebr_data_t *esm_ebr_data)
 {
   int i;
 
-  for (i = _esm_ebr_data[ueid].index; i < ESM_EBR_DATA_SIZE; i++) {
-    if (_esm_ebr_data[ueid].context[i] != NULL) {
+  for (i = esm_ebr_data->index; i < ESM_EBR_DATA_SIZE; i++) {
+    if (esm_ebr_data->context[i] != NULL) {
       continue;
     }
 
     return i;
   }
 
-  for (i = 0; i < _esm_ebr_data[ueid].index; i++) {
-    if (_esm_ebr_data[ueid].context[i] != NULL) {
+  for (i = 0; i < esm_ebr_data->index; i++) {
+    if (esm_ebr_data->context[i] != NULL) {
       continue;
     }
 
diff --git a/openair3/NAS/UE/ESM/esm_ebr.h b/openair3/NAS/UE/ESM/esm_ebr.h
index af31e95676a..adc10de0c45 100644
--- a/openair3/NAS/UE/ESM/esm_ebr.h
+++ b/openair3/NAS/UE/ESM/esm_ebr.h
@@ -45,6 +45,7 @@ Description Defines functions used to handle state of EPS bearer contexts
 #include "esmData.h"
 
 #include "nas_timer.h"
+#include "user_defs.h"
 
 /****************************************************************************/
 /*********************  G L O B A L    C O N S T A N T S  *******************/
@@ -72,15 +73,17 @@ typedef int (*esm_indication_callback_t) (int, network_pdn_state_t);
 /******************  E X P O R T E D    F U N C T I O N S  ******************/
 /****************************************************************************/
 
-int esm_ebr_is_reserved(int ebi);
+void esm_ebr_register_callback(esm_indication_callback_t cb);
 
-void esm_ebr_initialize(esm_indication_callback_t cb);
-int esm_ebr_assign(int ebi, int cid, int default_ebr);
-int esm_ebr_release(int ebi);
+int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi);
 
-int esm_ebr_set_status(int ebi, esm_ebr_state status, int ue_requested);
-esm_ebr_state esm_ebr_get_status(int ebi);
+esm_ebr_data_t *esm_ebr_initialize(void);
+int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, int default_ebr);
+int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, int ebi);
 
-int esm_ebr_is_not_in_use(int ebi);
+int esm_ebr_set_status(esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, int ue_requested);
+esm_ebr_state esm_ebr_get_status(esm_ebr_data_t *esm_ebr_data, int ebi);
+
+int esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi);
 
 #endif /* __ESM_EBR_H__*/
diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c
index 00950428bb0..1f7707c5c30 100644
--- a/openair3/NAS/UE/ESM/esm_ebr_context.c
+++ b/openair3/NAS/UE/ESM/esm_ebr_context.c
@@ -82,7 +82,7 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *,
  ** Description: Creates a new EPS bearer context to the PDN with the spe- **
  **      cified PDN connection identifier                          **
  **                                                                        **
- ** Inputs:  ueid:      UE identifier                              **
+ ** Inputs: **
  **      pid:       PDN connection identifier                  **
  **      ebi:       EPS bearer identity                        **
  **      is_default:    TRUE if the new bearer is a default EPS    **
@@ -105,7 +105,6 @@ int esm_ebr_context_create(
   int                 bid     = 0;
   esm_data_context_t *esm_ctx = NULL;
   esm_pdn_t          *pdn     = NULL;
-  //unsigned int        ueid    = 0;
 
   LOG_FUNC_IN;
 
@@ -314,7 +313,7 @@ int esm_ebr_context_create(
  ** Description: Releases EPS bearer context entry previously allocated    **
  **      to the EPS bearer with the specified EPS bearer identity  **
  **                                                                        **
- ** Inputs:  ueid:      UE identifier                              **
+ ** Inputs:   **
  **      ebi:       EPS bearer identity                        **
  **                                                                        **
  ** Outputs:     pid:       Identifier of the PDN connection entry the **
@@ -333,8 +332,6 @@ int esm_ebr_context_release(nas_user_t *user,
   esm_pdn_t *pdn = NULL;
   esm_data_context_t *esm_ctx;
 
-  //unsigned int ueid = 0;
-
   LOG_FUNC_IN;
 
   esm_ctx = user->esm_data;
@@ -451,11 +448,11 @@ int esm_ebr_context_release(nas_user_t *user,
           }
 
           /* Set the EPS bearer context state to INACTIVE */
-          (void) esm_ebr_set_status(pdn->bearer[i]->ebi,
+          esm_ebr_set_status(user->esm_ebr_data, pdn->bearer[i]->ebi,
                                     ESM_EBR_INACTIVE, TRUE);
 
           /* Release EPS bearer data */
-          (void) esm_ebr_release(pdn->bearer[i]->ebi);
+          esm_ebr_release(user->esm_ebr_data, pdn->bearer[i]->ebi);
 
           // esm_ebr_release()
           /* Release dedicated EPS bearer data */
diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c
index b14dd3e471f..f79b40cfecf 100644
--- a/openair3/NAS/UE/ESM/esm_main.c
+++ b/openair3/NAS/UE/ESM/esm_main.c
@@ -102,8 +102,9 @@ void esm_main_initialize(nas_user_t *user, esm_indication_callback_t cb)
   user->esm_pt_data = esm_pt_initialize();
 
   /* Initialize the EPS bearer context manager */
-  esm_ebr_initialize(cb);
-
+  user->esm_ebr_data = esm_ebr_initialize();
+  // FIXME only one callback for all user or many for many ?
+  esm_ebr_register_callback(cb);
   LOG_FUNC_OUT;
 }
 
@@ -247,11 +248,13 @@ int esm_main_has_emergency(esm_data_t *esm_data)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int esm_main_get_pdn_status(esm_data_t *esm_data, int cid, int *state)
+int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state)
 {
   LOG_FUNC_IN;
 
   unsigned int pid = cid - 1;
+  esm_data_t *esm_data = user->esm_data;
+  esm_ebr_data_t *esm_ebr_data = user-> esm_ebr_data;
 
   if (pid >= ESM_DATA_PDN_MAX) {
     return (FALSE);
@@ -268,7 +271,7 @@ int esm_main_get_pdn_status(esm_data_t *esm_data, int cid, int *state)
     /* 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;
-    *state = (esm_ebr_get_status(ebi) == ESM_EBR_ACTIVE);
+    *state = (esm_ebr_get_status(esm_ebr_data, ebi) == ESM_EBR_ACTIVE);
   }
 
   /* The PDN connection has not been activated yet */
diff --git a/openair3/NAS/UE/ESM/esm_main.h b/openair3/NAS/UE/ESM/esm_main.h
index 99fe4ba38f2..42381c8d5b1 100644
--- a/openair3/NAS/UE/ESM/esm_main.h
+++ b/openair3/NAS/UE/ESM/esm_main.h
@@ -70,7 +70,7 @@ void esm_main_cleanup(esm_data_t *esm_data);
 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_status(nas_user_t *user, 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(esm_data_t *esm_data, int cid, const char **ipv4addr, const char **ipv6addr);
diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c
index 9d4d3625ffc..68304f08790 100644
--- a/openair3/NAS/UE/nas_proc.c
+++ b/openair3/NAS/UE/nas_proc.c
@@ -674,7 +674,7 @@ int nas_proc_get_pdn_range(esm_data_t *esm_data)
  **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int nas_proc_get_pdn_status(esm_data_t *esm_data, int *cids, int *states, int n_pdn_max)
+int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_max)
 {
   LOG_FUNC_IN;
 
@@ -682,13 +682,13 @@ int nas_proc_get_pdn_status(esm_data_t *esm_data, int *cids, int *states, int n_
   int n_defined_pdn = 0;
 
   /* Get the maximum number of supported PDN contexts */
-  int n_pdn = esm_main_get_nb_pdns_max(esm_data);
+  int n_pdn = esm_main_get_nb_pdns_max(user->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(esm_data, cid, &state);
+    int is_defined = esm_main_get_pdn_status(user, cid, &state);
 
     if (is_defined != FALSE) {
       /* This PDN has been defined */
diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h
index 6851746d384..ec1ca3f3c78 100644
--- a/openair3/NAS/UE/nas_proc.h
+++ b/openair3/NAS/UE/nas_proc.h
@@ -98,7 +98,7 @@ 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(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_status(nas_user_t *user, 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,
diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c
index 909c82a393d..827003699c4 100644
--- a/openair3/NAS/UE/nas_user.c
+++ b/openair3/NAS/UE/nas_user.c
@@ -2184,7 +2184,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->esm_data, cgact->cid, cgact->state,
+    cgact->n_pdns = nas_proc_get_pdn_status(user, cgact->cid, cgact->state,
                                             AT_CGACT_RESP_SIZE);
 
     if (cgact->n_pdns == 0) {
diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h
index a27d6f5177c..a963960f4fe 100644
--- a/openair3/NAS/UE/user_defs.h
+++ b/openair3/NAS/UE/user_defs.h
@@ -56,6 +56,7 @@ typedef struct {
   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
 } nas_user_t;
 
 #endif
-- 
GitLab