From 4deb58339b20fe6393dd10900cb547506b5bbc01 Mon Sep 17 00:00:00 2001
From: luis_pereira87 <lpereira@allbesmart.pt>
Date: Fri, 7 Jul 2023 11:01:04 +0100
Subject: [PATCH] Fix multiple PDUSessions after review, now DRBs are
 configured sequentially, no matter what PDUSession id we receive

---
 openair2/E1AP/e1ap.c                    |   9 +-
 openair2/RRC/NR/rrc_gNB.c               | 112 ++++++++++++------------
 openair2/RRC/NR/rrc_gNB_NGAP.c          |   8 +-
 openair2/RRC/NR/rrc_gNB_radio_bearers.c |  18 +---
 4 files changed, 63 insertions(+), 84 deletions(-)

diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c
index 7a1954f714..6c33ddf973 100644
--- a/openair2/E1AP/e1ap.c
+++ b/openair2/E1AP/e1ap.c
@@ -589,14 +589,7 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_setup_req_t *setup, e1ap_beare
 
     for (DRB_nGRAN_to_setup_t *j=i->DRBnGRanList; j < i->DRBnGRanList+i->numDRB2Setup; j++) {
       asn1cSequenceAdd(ieC6_1->dRB_To_Setup_List_NG_RAN.list, E1AP_DRB_To_Setup_Item_NG_RAN_t, ieC6_1_1);
-
-      ieC6_1_1->dRB_ID = ieC6_1->pDU_Session_ID;
-      LOG_W(E1AP,
-            "%s: %d Current implementation configures one DRB per PDUSession, ieC6_1->pDU_Session_ID %ld, ieC6_1_1->dRB_ID %ld\n",
-            __FUNCTION__,
-            __LINE__,
-            ieC6_1->pDU_Session_ID,
-            ieC6_1_1->dRB_ID);
+      ieC6_1_1->dRB_ID = j->id;
 
       ieC6_1_1->sDAP_Configuration.defaultDRB = j->defaultDRB;
       ieC6_1_1->sDAP_Configuration.sDAP_Header_UL = j->sDAP_Header_UL;
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 05df1da23c..776c6b9275 100644
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -114,43 +114,6 @@ mui_t rrc_gNB_mui = 0;
 ///---------------------------------------------------------------------------------------------------------------///
 ///---------------------------------------------------------------------------------------------------------------///
 
-static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish)
-{
-  if (!ue->Srb[1].Active) {
-    LOG_E(NR_RRC, "Call SRB list while SRB1 doesn't exist\n");
-    return NULL;
-  }
-  NR_SRB_ToAddModList_t *list = CALLOC(sizeof(*list), 1);
-  for (int i = 0; i < maxSRBs; i++) {
-    if (ue->Srb[i].Active) {
-      asn1cSequenceAdd(list->list, NR_SRB_ToAddMod_t, srb);
-      srb->srb_Identity = i;
-      if (reestablish && i == 2) {
-        asn1cCallocOne(srb->reestablishPDCP, NR_SRB_ToAddMod__reestablishPDCP_true);
-      }
-    }
-  }
-  return list;
-}
-
-// not clear what this function do against fill_DRB_configList()
-// it sets reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true
-// else it should probably be removed and merged into fill_DRB_configList
-static NR_DRB_ToAddModList_t *createDRBlistReestablish(gNB_RRC_UE_t *ue)
-{
-  NR_DRB_ToAddMod_t *DRB_config = NULL;
-  NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1);
-
-  for (int i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) {
-    if (ue->established_drbs[i].status != DRB_INACTIVE) {
-      ue->established_drbs[i].reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true;
-      DRB_config = generateDRB_ASN1(&ue->established_drbs[i]);
-      asn1cSeqAdd(&DRB_configList->list, DRB_config);
-    }
-  }
-  return DRB_configList;
-}
-
 NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue)
 {
   gNB_RRC_INST *rrc = RC.nrrrc[0];
@@ -413,6 +376,42 @@ unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP)
   return tmp;
 }
 
+static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish)
+{
+  if (!ue->Srb[1].Active) {
+    LOG_E(NR_RRC, "Call SRB list while SRB1 doesn't exist\n");
+    return NULL;
+  }
+  NR_SRB_ToAddModList_t *list = CALLOC(sizeof(*list), 1);
+  for (int i = 0; i < maxSRBs; i++)
+    if (ue->Srb[i].Active) {
+      asn1cSequenceAdd(list->list, NR_SRB_ToAddMod_t, srb);
+      srb->srb_Identity = i;
+      if (reestablish && i == 2) {
+        asn1cCallocOne(srb->reestablishPDCP, NR_SRB_ToAddMod__reestablishPDCP_true);
+      }
+    }
+  return list;
+}
+
+static NR_DRB_ToAddModList_t *createDRBlist(gNB_RRC_UE_t *ue, bool reestablish)
+{
+  NR_DRB_ToAddMod_t *DRB_config = NULL;
+  NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1);
+
+  for (int i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) {
+    if (ue->established_drbs[i].status != DRB_INACTIVE) {
+      DRB_config = generateDRB_ASN1(&ue->established_drbs[i]);
+      if (reestablish) {
+        ue->established_drbs[i].reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true;
+        asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true);
+      }
+      asn1cSeqAdd(&DRB_configList->list, DRB_config);
+    }
+  }
+  return DRB_configList;
+}
+
 static void freeSRBlist(NR_SRB_ToAddModList_t *l)
 {
   if (l) {
@@ -744,7 +743,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
 
   uint8_t buffer[RRC_BUF_SIZE] = {0};
   NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false);
-  NR_DRB_ToAddModList_t *DRBs = createDRBlistReestablish(ue_p);
+  NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, false);
 
   int size = do_RRCReconfiguration(ctxt_pP,
                                    buffer,
@@ -1034,7 +1033,7 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co
   uint8_t kUPenc[16] = {0};
   uint8_t kUPint[16] = {0};
   gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
-  NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(ue_p);
+  NR_DRB_ToAddModList_t *DRB_configList = createDRBlist(ue_p, false);
 
   /* Derive the keys from kgnb */
   if (DRB_configList != NULL) {
@@ -1048,18 +1047,20 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co
   /* Refresh SRBs/DRBs */
   LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_p->rnti);
   ue_id_t reestablish_ue_id = 0;
-  if (DRB_configList && DRB_configList->list.array[0]->reestablishPDCP && *DRB_configList->list.array[0]->reestablishPDCP == NR_DRB_ToAddMod__reestablishPDCP_true) {
-    for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
-      nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[i];
-      if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) {
-        ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++;
-        reestablish_ue_id = nr_reestablish_rnti_map[i].c_rnti;
-        LOG_D(NR_RRC, "Removing reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti);
-        // clear current C-RNTI from map
-        nr_reestablish_rnti_map->ue_id = 0;
-        nr_reestablish_rnti_map->c_rnti = 0;
-        break;
-      }
+  for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
+    nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[i];
+    if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) {
+      ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++;
+      reestablish_ue_id = nr_reestablish_rnti_map[i].c_rnti;
+      LOG_D(NR_RRC,
+            "Removing reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n",
+            i,
+            nr_reestablish_rnti_map->ue_id,
+            nr_reestablish_rnti_map->c_rnti);
+      // clear current C-RNTI from map
+      nr_reestablish_rnti_map->ue_id = 0;
+      nr_reestablish_rnti_map->c_rnti = 0;
+      break;
     }
   }
   NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false);
@@ -1346,15 +1347,16 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
                    NR_RLC_BearerConfig__reestablishRLC_true);
   }
 
-  NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(ue_p);
-  uint8_t buffer[RRC_BUF_SIZE] = {0};
   NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true);
+  NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, true);
+
+  uint8_t buffer[RRC_BUF_SIZE] = {0};
   int size = do_RRCReconfiguration(ctxt_pP,
                                    buffer,
                                    RRC_BUF_SIZE,
                                    new_xid,
                                    SRBs,
-                                   DRB_configList,
+                                   DRBs,
                                    NULL,
                                    NULL,
                                    NULL,
@@ -1366,7 +1368,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
                                    NULL,
                                    cellGroupConfig);
   freeSRBlist(SRBs);
-  freeDRBlist(DRB_configList);
+  freeDRBlist(DRBs);
   LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n");
 
   RRCReestablishmentComplete_nas_pdu_free(ue_context_pP);
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index fd31004a17..f0a7f3b90f 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -778,13 +778,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
     for (int j=0; j < pdu->numDRB2Setup; j++) {
       DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j;
 
-      drb->id = session->pdusession_id;
-      LOG_W(NR_RRC,
-            "%s: %d Current implementation configures one DRB per PDUSession, session->pdusession_id %d, drb->id %ld\n",
-            __FUNCTION__,
-            __LINE__,
-            session->pdusession_id,
-            drb->id);
+      drb->id = i + j + UE->nb_of_pdusessions;
 
       drb->defaultDRB = E1AP_DefaultDRB_true;
 
diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c
index 57dcd35a9b..4c5c50fb00 100644
--- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c
+++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c
@@ -147,25 +147,15 @@ uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession
 {
   uint8_t drb_id;
 
-  drb_id = pdusession->param.pdusession_id;
-  LOG_W(NR_RRC,
-        "%s: %d Current implementation configures one DRB per PDUSession, pdusession_id %d, drb_id %d\n",
-        __FUNCTION__,
-        __LINE__,
-        pdusession->param.pdusession_id,
-        drb_id);
-
-  return drb_id;
-
-  if(!is_gbr) { /* Find if Non-GBR DRB exists in the same PDU Session */
+  if (0 /*!is_gbr*/) { /* Find if Non-GBR DRB exists in the same PDU Session */
     for (drb_id = 0; drb_id < NGAP_MAX_DRBS_PER_UE; drb_id++)
       if (pdusession->param.used_drbs[drb_id] == DRB_ACTIVE_NONGBR)
-        return drb_id+1;
+        return drb_id + 1;
   }
   /* GBR Flow  or a Non-GBR DRB does not exist in the same PDU Session, find an available DRB */
   for (drb_id = 0; drb_id < NGAP_MAX_DRBS_PER_UE; drb_id++)
-    if(ue->DRB_active[drb_id] == DRB_INACTIVE)
-      return drb_id+1;
+    if (ue->DRB_active[drb_id] == DRB_INACTIVE)
+      return drb_id + 1;
   /* From this point, we need to handle the case that all DRBs are already used by the UE. */
   LOG_E(RRC, "Error - All the DRBs are used - Handle this\n");
   return DRB_INACTIVE;
-- 
2.26.2