From e490faa60c6e9aec1bafc0b923ca08682e301221 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 17 Sep 2025 11:42:39 +0200 Subject: [PATCH] E1AP: add DRB To Remove list to E1 Bearer Context Modification lib Add DRB To Remove List IE to PDU Session To Modify list, which is sent in the Bearer Context Modification request. This allows the CUCP to inform the CUUP about DRBs to be released in a specific PDU session during a MODIFY procedure. Changes: * Add struct definition * Add enc/dec/eq/cp func * Add test --- openair2/COMMON/e1ap_messages_types.h | 9 +++++++ .../E1AP/lib/e1ap_bearer_context_management.c | 24 +++++++++++++++++++ openair2/E1AP/lib/e1ap_lib_includes.h | 2 ++ openair2/E1AP/tests/e1ap_lib_test.c | 2 ++ openair2/RRC/NR/rrc_gNB.c | 1 + 5 files changed, 38 insertions(+) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 711c126dab..01a5d6b260 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -409,6 +409,12 @@ typedef struct DRB_nGRAN_to_modify_s { qos_flow_to_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS]; } DRB_nGRAN_to_mod_t; +/* DRB To Remove Item (NG-RAN) clause 9.3.1.11 */ +typedef struct { + // DRB ID (M) + long id; +} drb_to_remove_t; + typedef enum e1ap_indication_e { SECURITY_REQUIRED = 0, SECURITY_PREFERRED, @@ -472,6 +478,9 @@ typedef struct pdu_session_to_mod_s { long numDRB2Modify; // DRB To Modify Item (1..) DRB_nGRAN_to_mod_t DRBnGRanModList[E1AP_MAX_NUM_DRBS]; + // DRB To Remove List (0..maxnoofDRBs) + int n_drb_to_remove; + drb_to_remove_t drbs_to_remove[E1AP_MAX_NUM_DRBS]; } pdu_session_to_mod_t; /** PDU Session Resource To Remove List (3GPP TS 38.463 clause 9.3.3.12) */ diff --git a/openair2/E1AP/lib/e1ap_bearer_context_management.c b/openair2/E1AP/lib/e1ap_bearer_context_management.c index f2593f103c..95245d8492 100644 --- a/openair2/E1AP/lib/e1ap_bearer_context_management.c +++ b/openair2/E1AP/lib/e1ap_bearer_context_management.c @@ -1465,6 +1465,14 @@ static E1AP_PDU_Session_Resource_To_Modify_Item_t e1_encode_pdu_session_to_mod_i *ie1_2 = e1_encode_qos_flow_to_setup(k); } } + // DRB To Remove List (O) + if (in->n_drb_to_remove > 0) { + asn1cCalloc(out.dRB_To_Remove_List_NG_RAN, drb2Remove_List); + for (int r = 0; r < in->n_drb_to_remove; r++) { + asn1cSequenceAdd(drb2Remove_List->list, E1AP_DRB_To_Remove_Item_NG_RAN_t, drb2Rem); + drb2Rem->dRB_ID = in->drbs_to_remove[r].id; + } + } return out; } @@ -1746,6 +1754,15 @@ static bool e1_decode_pdu_session_to_mod_item(pdu_session_to_mod_t *out, const E } } } + // DRB To Remove List (O) + if (in->dRB_To_Remove_List_NG_RAN) { + E1AP_DRB_To_Remove_List_NG_RAN_t *rm = in->dRB_To_Remove_List_NG_RAN; + out->n_drb_to_remove = rm->list.count; + for (int r = 0; r < rm->list.count; r++) { + E1AP_DRB_To_Remove_Item_NG_RAN_t *item = rm->list.array[r]; + out->drbs_to_remove[r].id = item->dRB_ID; + } + } return true; } @@ -1931,6 +1948,9 @@ static pdu_session_to_mod_t cp_pdu_session_to_mod_item(const pdu_session_to_mod_ // DRB to modify list for (int j = 0; j < msg->numDRB2Modify; j++) cp.DRBnGRanModList[j] = cp_drb_to_mod_item(&msg->DRBnGRanModList[j]); + // DRB to remove list + for (int r = 0; r < msg->n_drb_to_remove; r++) + cp.drbs_to_remove[r] = msg->drbs_to_remove[r]; _E1_CP_OPTIONAL_IE(&cp, msg, securityIndication); _E1_CP_OPTIONAL_IE(&cp, msg, UP_TL_information); return cp; @@ -2021,6 +2041,10 @@ static bool eq_pdu_session_to_mod_item(const pdu_session_to_mod_t *a, const pdu_ return false; } _E1_EQ_CHECK_OPTIONAL_PTR(a, b, securityIndication); + _E1_EQ_CHECK_INT(a->n_drb_to_remove, b->n_drb_to_remove); + for (int r = 0; r < a->n_drb_to_remove; r++) { + _E1_EQ_CHECK_LONG(a->drbs_to_remove[r].id, b->drbs_to_remove[r].id); + } if (a->securityIndication && b->securityIndication) { if (!eq_security_ind(a->securityIndication, b->securityIndication)) return false; diff --git a/openair2/E1AP/lib/e1ap_lib_includes.h b/openair2/E1AP/lib/e1ap_lib_includes.h index adafbe0ae5..f58875a306 100644 --- a/openair2/E1AP/lib/e1ap_lib_includes.h +++ b/openair2/E1AP/lib/e1ap_lib_includes.h @@ -76,6 +76,8 @@ #include "E1AP_PDU-Session-Resource-To-Modify-Item.h" #include "E1AP_DRB-To-Modify-List-NG-RAN.h" #include "E1AP_DRB-To-Modify-Item-NG-RAN.h" +#include "E1AP_DRB-To-Remove-List-NG-RAN.h" +#include "E1AP_DRB-To-Remove-Item-NG-RAN.h" #include "E1AP_PDU-Session-Resource-To-Setup-Mod-Item.h" #include "E1AP_DRB-To-Setup-Mod-Item-NG-RAN.h" #include "E1AP_PDU-Session-Resource-To-Remove-Item.h" diff --git a/openair2/E1AP/tests/e1ap_lib_test.c b/openair2/E1AP/tests/e1ap_lib_test.c index 50116514fb..e11cacc241 100644 --- a/openair2/E1AP/tests/e1ap_lib_test.c +++ b/openair2/E1AP/tests/e1ap_lib_test.c @@ -515,6 +515,8 @@ static void test_bearer_context_modification_request(void) .sessionId = 1, .numDRB2Modify = 1, .DRBnGRanModList[0] = drb_to_mod, + .n_drb_to_remove = 1, + .drbs_to_remove[0].id = 2, }; DRB_nGRAN_to_setup_t drb_to_setup = { diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 6b914c27e9..2434cabba3 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2879,6 +2879,7 @@ static int fill_drb_to_be_setup_from_e1_resp(const gNB_RRC_INST *rrc, /* pass QoS info to MAC */ int nb_qos_flows = drb_config->numQosFlowSetup; AssertFatal(nb_qos_flows > 0, "must map at least one flow to a DRB\n"); + DevAssert(nb_qos_flows <= MAX_QOS_FLOWS); drb->nr.flows_len = nb_qos_flows; drb->nr.flows = calloc_or_fail(nb_qos_flows, sizeof(*drb->nr.flows)); for (int j = 0; j < nb_qos_flows; j++) {