From 7fa0ebb6b9a933f9114fb21840e23ecc03375afe Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 4 Jul 2025 17:23:14 +0200 Subject: [PATCH] Adopt dynamic seq_arr in DRB handling (RRC PDU Session) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous DRB management relied on a fixed-size array (established_drbs[MAX_DRBS_PER_UE]) and manual status tracking using DRB_ACTIVE/INACTIVE flags. This approach was inefficient, and made assumptions about DRB ID allocation that do not generalize well to dynamic procedures like bearer modification or removal. * Replace fixed-size array established_drbs[] with dynamic seq_arr_t *drbs in gNB_RRC_UE_t * Refactor get_drb() and added nr_rrc_add_drb() with clean abstractions using find and seq_arr lib * Updated all DRB-related logic (e.g., generateDRB, F1AP/E1AP tunnel config, reestablishment, mobility) to use seq_arr. * Removed status field and DRB_ACTIVE/INACTIVE logic: list presence implies active * DRB ID allocation now tracked via seq_arr size : simplifies DRB management and avoids DRB ID–indexed assumptions: code assumed DRB IDs mapped directly to array indices: established_drbs[drb_id - 1]. This could break when: DRB IDs are not sequential, DRBs are removed and re-added, or there are gaps in IDs --- openair2/RRC/NR/nr_rrc_defs.h | 3 +- openair2/RRC/NR/rrc_gNB.c | 59 ++++++------- openair2/RRC/NR/rrc_gNB_NGAP.c | 24 ++++-- openair2/RRC/NR/rrc_gNB_NGAP.h | 6 +- openair2/RRC/NR/rrc_gNB_UE_context.c | 2 + openair2/RRC/NR/rrc_gNB_mobility.c | 8 +- openair2/RRC/NR/rrc_gNB_mobility.h | 6 +- openair2/RRC/NR/rrc_gNB_radio_bearers.c | 108 ++++++++++++++---------- openair2/RRC/NR/rrc_gNB_radio_bearers.h | 21 ++--- 9 files changed, 133 insertions(+), 104 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 4f06fbd0d0..43909e0cd0 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -182,7 +182,6 @@ typedef struct nr_handover_context_s nr_handover_context_t; typedef struct gNB_RRC_UE_s { time_t last_seen; // last time this UE has been accessed - drb_t established_drbs[MAX_DRBS_PER_UE]; NR_DRB_ToReleaseList_t *DRB_ReleaseList; NR_SRB_INFO_TABLE_ENTRY Srb[NR_NUM_SRB]; @@ -239,6 +238,8 @@ typedef struct gNB_RRC_UE_s { //SA block seq_arr_t pduSessions; + // Established DRBs + seq_arr_t drbs; rrc_action_t xids[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; uint8_t e_rab_release_command_flag; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index ca8a46a705..1919ccaa5c 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -334,14 +334,12 @@ 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 < MAX_DRBS_PER_UE; i++) { - if (ue->established_drbs[i].status != DRB_INACTIVE) { - DRB_config = generateDRB_ASN1(&ue->established_drbs[i]); - if (reestablish) { - asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true); - } - asn1cSeqAdd(&DRB_configList->list, DRB_config); + FOR_EACH_SEQ_ARR(drb_t *, drb, &ue->drbs) { + DRB_config = generateDRB_ASN1(drb); + if (reestablish) { + asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true); } + asn1cSeqAdd(&DRB_configList->list, DRB_config); } if (DRB_configList->list.count == 0) { free(DRB_configList); @@ -734,22 +732,6 @@ void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t continue; } - // search exist DRB_config - int j; - for (j = 0; j < MAX_DRBS_PER_UE; j++) { - if (ue_p->established_drbs[j].status != DRB_INACTIVE - && ue_p->established_drbs[j].cnAssociation.sdap_config.pdusession_id == session->pdusession_id) - break; - } - - if (j == MAX_DRBS_PER_UE) { - ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CauseRadioNetwork_unspecified}; - item->xid = params.transaction_id; - item->status = PDU_SESSION_STATUS_FAILED; - item->cause = cause; - continue; - } - // Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping for (qos_flow_index = 0; qos_flow_index < session->nb_qos; qos_flow_index++) { pdusession_level_qos_parameter_t *qos = &session->qos[qos_flow_index]; @@ -873,8 +855,8 @@ static void cuup_notify_reestablishment(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p) return; /* loop through active DRBs */ for (int drb_id = 1; drb_id <= MAX_DRBS_PER_UE; drb_id++) { - drb_t *drb = get_drb(ue_p, drb_id); - if (drb->status == DRB_INACTIVE) + drb_t *drb = get_drb(&ue_p->drbs, drb_id); + if (!drb) continue; /* fetch an existing PDU session for this DRB */ rrc_pdu_session_param_t *pdu = find_pduSession_from_drbId(ue_p, drb_id); @@ -2078,7 +2060,8 @@ static void store_du_f1u_tunnel(const f1ap_drb_setup_t *drbs, int n, gNB_RRC_UE_ const f1ap_drb_setup_t *drb_f1 = &drbs[i]; AssertFatal(drb_f1->up_dl_tnl_len == 1, "can handle only one UP param\n"); AssertFatal(drb_f1->id < MAX_DRBS_PER_UE, "illegal DRB ID %d\n", drb_f1->id); - drb_t *drb = get_drb(ue, drb_f1->id); + drb_t *drb = get_drb(&ue->drbs, drb_f1->id); + DevAssert(drb); drb->du_tunnel_config = f1u_gtp_update(drb_f1->up_dl_tnl[0].teid, drb_f1->up_dl_tnl[0].tl_address); } } @@ -2094,7 +2077,7 @@ static void fill_e1_bearer_modif_pdcp_status(gNB_RRC_UE_t *UE, drb_to_mod->pdcp_sn_status_requested = false; // PDCP SN Status Information drb_to_mod->pdcp_config = calloc_or_fail(1, sizeof(*drb_to_mod->pdcp_config)); - set_bearer_context_pdcp_config(drb_to_mod->pdcp_config, get_drb(UE, drb_id), um_on_default_drb); + set_bearer_context_pdcp_config(drb_to_mod->pdcp_config, get_drb(&UE->drbs, drb_id), um_on_default_drb); drb_to_mod->pdcp_status = calloc_or_fail(1, sizeof(*drb_to_mod->pdcp_status)); drb_to_mod->pdcp_status->dl_count.hfn = drb_status->dl_count.hfn; drb_to_mod->pdcp_status->dl_count.sn = drb_status->dl_count.pdcp_sn; @@ -2130,8 +2113,11 @@ void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f1ap_drb fill_e1_bearer_modif(&drb_to_mod, drb_f1); } else if (is_inter_cu_ho) { /* On-going handover: send PDCP Status Request */ - if (UE->established_drbs[i].status == DRB_INACTIVE) + drb_t *drb = get_drb(&UE->drbs, drb_id); + if (!drb) { + LOG_E(NR_RRC, "Failed to send PDCP Status Request: DRB %d not found\n", drb_id); continue; + } drb_to_mod.id = drb_id; // PDCP SN Status Request drb_to_mod.pdcp_sn_status_requested = true; @@ -2204,7 +2190,7 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance } if (resp->drbs_len > 0) { - int num_drb = get_number_active_drbs(UE); + int num_drb = seq_arr_size(&UE->drbs); DevAssert(num_drb == 0 || num_drb == resp->drbs_len); /* Note: we would ideally check that SRB2 is acked, but at least LiteOn DU @@ -2296,6 +2282,7 @@ static void rrc_delete_ue_data(gNB_RRC_UE_t *UE) free(UE->redcap_cap); UE->redcap_cap = NULL; seq_arr_free(&UE->pduSessions, free_pdusession); + seq_arr_free(&UE->drbs, free_drb); } void rrc_remove_ue(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p) @@ -2510,9 +2497,10 @@ static int fill_drb_to_be_setup_from_e1_resp(const gNB_RRC_INST *rrc, DevAssert(pdu); for (int i = 0; i < pduSession[p].numDRBSetup; i++) { const DRB_nGRAN_setup_t *drb_config = &pduSession[p].DRBnGRanList[i]; - drb_t *rrc_drb = get_drb(UE, pduSession[p].DRBnGRanList[i].id); + drb_t *rrc_drb = get_drb(&UE->drbs, pduSession[p].DRBnGRanList[i].id); DevAssert(rrc_drb); + DevAssert(nb_drb < MAX_DRBS_PER_UE); f1ap_drb_to_setup_t *drb = &drbs[nb_drb]; drb->id = rrc_drb->drb_id; @@ -2587,7 +2575,11 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp DRB_nGRAN_setup_t *drb_config = &e1_pdu->DRBnGRanList[j]; // numUpParam only relevant in F1, but not monolithic AssertFatal(drb_config->numUpParam <= 1, "can only up to one UP param\n"); - drb_t *drb = get_drb(UE, drb_config->id); + drb_t *drb = get_drb(&UE->drbs, drb_config->id); + if (!drb) { + LOG_E(RRC, "E1: DRB %ld not found for PDU session %ld\n", drb_config->id, e1_pdu->id); + continue; + } UP_TL_information_t *tl_info = &drb_config->UpParamList[0].tl_info; drb->cuup_tunnel_config = f1u_gtp_update(tl_info->teId, tl_info->tlAddress); } @@ -2629,6 +2621,7 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t } int n_drb_mod = 0; + int drb_ids[MAX_DRBS_PER_UE] = {0}; e1_pdcp_status_info_t pdcp_status[MAX_DRBS_PER_UE] = {0}; for (int i = 0; i < resp->numPDUSessionsMod; ++i) { const pdu_session_modif_t *pdu = &resp->pduSessionMod[i]; @@ -2636,6 +2629,8 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t for (int j = 0; j < pdu->numDRBModified; j++) { // Trigger UL RAN Status Transfer if (pdu->DRBnGRanModList[j].pdcp_status) { + DevAssert(n_drb_mod < MAX_DRBS_PER_UE); + drb_ids[n_drb_mod] = pdu->DRBnGRanModList[j].id; pdcp_status[n_drb_mod++] = *pdu->DRBnGRanModList[j].pdcp_status; } } @@ -2644,7 +2639,7 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t LOG_I(NR_RRC, "UE %d: received PDU Status Info - send UL RAN Status Transfer\n", resp->gNB_cu_cp_ue_id); gNB_RRC_UE_t *ue = &ue_context_p->ue_context; if (ue->ho_context && ue->ho_context->source) - ue->ho_context->source->ho_status_transfer(rrc, ue, n_drb_mod, pdcp_status); + ue->ho_context->source->ho_status_transfer(rrc, ue, n_drb_mod, drb_ids, pdcp_status); } } diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index b1f1e3fc85..ddf97b2499 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -315,9 +315,7 @@ bool trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession /* we assume for the moment one DRB per PDU session. Activate the bearer, * and configure in RRC. */ - int drb_id = get_next_available_drb_id(UE); drb_t *rrc_drb = generateDRB(UE, - drb_id, session, rrc->configuration.enable_sdap, rrc->security.do_drb_integrity, @@ -1162,9 +1160,15 @@ void rrc_gNB_free_Handover_Request(ngap_handover_request_t *msg) /** @brief Send NG Uplink RAN Status Transfer message (8.4.6 3GPP TS 38.413) * Direction: source NG-RAN node -> AMF */ -int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const int n_to_mod, const e1_pdcp_status_info_t *pdcp_status) +int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc, + gNB_RRC_UE_t *UE, + const int n_to_mod, + const int *drb_ids, + const e1_pdcp_status_info_t *pdcp_status) { AssertFatal(UE != NULL, "UE context is NULL\n"); + DevAssert(n_to_mod <= MAX_DRBS_PER_UE); + DevAssert(drb_ids); LOG_I(NR_RRC, "Sending NGAP Uplink RAN Status Transfer (AMF_UE_NGAP_ID=%" PRIu64 ", GNB_UE_NGAP_ID=%u)\n", @@ -1178,14 +1182,20 @@ int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE // Loop through DRBs and extract COUNT values for (int i = 0; i < n_to_mod; ++i) { - drb_t *drb = &UE->established_drbs[i]; - if (!drb->status) + int drb_id = drb_ids[i]; + + // Find the DRB in the UE's DRB list + drb_t *drb = get_drb(&UE->drbs, drb_id); + if (!drb) { + LOG_E(NR_RRC, "Failed to send UL RAN Status Transfer: DRB %d not found\n", drb_id); continue; + } - bool sn_length_18 = rrc->pdcp_config.drb.sn_size == 18; + bool sn_length_18 = drb->pdcp_config.pdcp_SN_SizeDL == NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; + DevAssert(msg.ran_status.nb_drb < MAX_DRBS_PER_UE); ngap_drb_status_t *item = &msg.ran_status.drb_status_list[msg.ran_status.nb_drb++]; - item->drb_id = drb->drb_id; + item->drb_id = drb_id; const e1_pdcp_count_t *ul_pdcp = &pdcp_status[i].ul_count; const e1_pdcp_count_t *dl_pdcp = &pdcp_status[i].dl_count; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h index c07cb04be0..91c7722c52 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.h +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -104,7 +104,11 @@ void rrc_gNB_free_Handover_Command(ngap_handover_command_t *msg); void rrc_gNB_send_NGAP_HANDOVER_NOTIFY(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE); void rrc_gNB_send_NGAP_HANDOVER_CANCEL(int module_id, gNB_RRC_UE_t *UE, ngap_cause_t cause); -int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const int n_to_mod, const e1_pdcp_status_info_t *pdcp_status); +int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc, + gNB_RRC_UE_t *UE, + const int n_to_mod, + const int *drb_ids, + const e1_pdcp_status_info_t *pdcp_status); int rrc_gNB_process_NGAP_DL_RAN_STATUS_TRANSFER(MessageDef *msg_p, instance_t instance); diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index d8d83505b9..412c5231cc 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -211,6 +211,8 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(sctp_assoc_t assoc_id, // Initialise setup PDU Sessions list seq_arr_init(&ue->pduSessions, sizeof(rrc_pdu_session_param_t)); + // Initialise setup DRBs list + seq_arr_init(&ue->drbs, sizeof(drb_t)); RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p); LOG_UE_EVENT(ue, diff --git a/openair2/RRC/NR/rrc_gNB_mobility.c b/openair2/RRC/NR/rrc_gNB_mobility.c index 40ff7d8ab2..3c17f45189 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.c +++ b/openair2/RRC/NR/rrc_gNB_mobility.c @@ -63,14 +63,14 @@ static void free_ho_ctx(nr_handover_context_t *ho_ctx) free(ho_ctx); } +/** @brief Fill DRB to Be Setup List in F1 UE Context Setup Request (optional list) + * @return 0 if list is empty, list size otherwise */ static int fill_drb_to_be_setup(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, f1ap_drb_to_setup_t drbs[MAX_DRBS_PER_UE]) { int nb_drb = 0; - for (int i = 0; i < MAX_DRBS_PER_UE; ++i) { - drb_t *rrc_drb = &ue->established_drbs[i]; - if (rrc_drb->status == DRB_INACTIVE) - continue; + FOR_EACH_SEQ_ARR(drb_t *, rrc_drb, &ue->drbs) { + DevAssert(nb_drb < MAX_DRBS_PER_UE); f1ap_drb_to_setup_t *drb = &drbs[nb_drb]; nb_drb++; /* fetch an existing PDU session for this DRB */ diff --git a/openair2/RRC/NR/rrc_gNB_mobility.h b/openair2/RRC/NR/rrc_gNB_mobility.h index 40072abb2d..7010cc83ba 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.h +++ b/openair2/RRC/NR/rrc_gNB_mobility.h @@ -33,7 +33,11 @@ typedef struct nr_rrc_du_container_t nr_rrc_du_container_t; typedef struct NR_CellGroupConfig NR_CellGroupConfig_t; typedef void (*ho_cancel_t)(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue); -typedef int (*ho_status_transfer_t)(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const int n_to_mod, const e1_pdcp_status_info_t *pdcp_status); +typedef int (*ho_status_transfer_t)(gNB_RRC_INST *rrc, + gNB_RRC_UE_t *UE, + const int n_to_mod, + const int *drb_ids, + const e1_pdcp_status_info_t *pdcp_status); typedef struct nr_ho_source_cu { /// pointer to the (source) DU structure diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index b55ce4e6ae..1f2f721eaa 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -85,26 +85,70 @@ rrc_pdu_session_param_t *add_pduSession(seq_arr_t *sessions_ptr, const pdusessio return added; } +/** @brief Add drb_t item in the UE context list for @param pdusession_id */ +drb_t *nr_rrc_add_drb(seq_arr_t *drb_ptr, int pdusession_id) +{ + DevAssert(drb_ptr); + + // Get next available DRB ID + int drb_id = 0; + + // First, try to find the lowest available ID (prefer smaller IDs) + for (drb_id = 1; drb_id <= MAX_DRBS_PER_UE; drb_id++) { + if (get_drb(drb_ptr, drb_id) == NULL) { + break; // Found available ID + } + } + + if (drb_id > MAX_DRBS_PER_UE) { + LOG_E(NR_RRC, "Cannot set up new DRB for pdusession_id=%d - reached maximum capacity\n", pdusession_id); + return NULL; + } + + // Add item to the list + drb_t in = {.drb_id = drb_id, .cnAssociation.sdap_config.pdusession_id = pdusession_id}; + seq_arr_push_back(drb_ptr, &in, sizeof(drb_t)); + drb_t *out = get_drb(drb_ptr, drb_id); + DevAssert(out); + LOG_I(NR_RRC, "Added DRB %d to established list (PDU Session ID=%d, total DRBs = %ld)\n", out->drb_id, pdusession_id, seq_arr_size(drb_ptr)); + return out; +} + +static bool eq_drb_id(const void *vval, const void *vit) +{ + const int id = *(const int *)vval; + const drb_t *elem = (const drb_t *)vit; + return elem->drb_id == id; +} + +/** @brief Retrieves DRB for the input ID + * @return pointer to the found DRB, NULL if not found */ +drb_t *get_drb(seq_arr_t *seq, int id) +{ + DevAssert(id > 0 && id <= MAX_DRBS_PER_UE); + elm_arr_t elm = find_if(seq, &id, eq_drb_id); + if (elm.found) + return (drb_t *)elm.it; + return NULL; +} + +/** @brief Free pdusession_t */ +void free_drb(void *ptr) +{ + // do nothing +} + rrc_pdu_session_param_t *find_pduSession_from_drbId(gNB_RRC_UE_t *ue, int drb_id) { - DevAssert(drb_id > 0 && drb_id <= 32); - const drb_t *drb = &ue->established_drbs[drb_id - 1]; - if (drb->status == DRB_INACTIVE) { - LOG_E(NR_RRC, "UE %d: DRB %d inactive\n", ue->rrc_ue_id, drb_id); + const drb_t *drb = get_drb(&ue->drbs, drb_id); + if (!drb) { + LOG_E(NR_RRC, "UE %d: DRB %d not found\n", ue->rrc_ue_id, drb_id); return NULL; } int id = drb->cnAssociation.sdap_config.pdusession_id; return find_pduSession(&ue->pduSessions, id); } -drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id) -{ - DevAssert(drb_id > 0 && drb_id <= 32); - DevAssert(ue != NULL); - - return &ue->established_drbs[drb_id - 1]; -} - void set_default_drb_pdcp_config(struct pdcp_config_s *pdcp_config, int do_drb_integrity, int do_drb_ciphering, @@ -139,7 +183,6 @@ void set_bearer_context_pdcp_config(bearer_context_pdcp_config_t *pdcp_config, d } drb_t *generateDRB(gNB_RRC_UE_t *ue, - uint8_t drb_id, const pdusession_t *pduSession, bool enable_sdap, int do_drb_integrity, @@ -148,13 +191,13 @@ drb_t *generateDRB(gNB_RRC_UE_t *ue, { DevAssert(ue != NULL); - LOG_I(NR_RRC, "UE %d: configure DRB ID %d for PDU session ID %d\n", ue->rrc_ue_id, drb_id, pduSession->pdusession_id); + drb_t *est_drb = nr_rrc_add_drb(&ue->drbs, pduSession->pdusession_id); + if (!est_drb) { + LOG_E(NR_RRC, "UE %d: failed to add DRB for PDU session ID %d\n", ue->rrc_ue_id, pduSession->pdusession_id); + return NULL; + } + LOG_I(NR_RRC, "UE %d: configure DRB ID %d for PDU session ID %d\n", ue->rrc_ue_id, est_drb->drb_id, pduSession->pdusession_id); - drb_t *est_drb = &ue->established_drbs[drb_id - 1]; - DevAssert(est_drb->status == DRB_INACTIVE); - - est_drb->status = DRB_ACTIVE; - est_drb->drb_id = drb_id; est_drb->cnAssociation.sdap_config.defaultDRB = true; /* SDAP Configuration */ @@ -169,16 +212,12 @@ drb_t *generateDRB(gNB_RRC_UE_t *ue, } for (int qos_flow_index = 0; qos_flow_index < pduSession->nb_qos; qos_flow_index++) { est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->qos[qos_flow_index].qfi; - if (pduSession->qos[qos_flow_index].fiveQI > 5) - est_drb->status = DRB_ACTIVE_NONGBR; - else - est_drb->status = DRB_ACTIVE; } /* PDCP Configuration */ set_default_drb_pdcp_config(&est_drb->pdcp_config, do_drb_integrity, do_drb_ciphering, pdcp_config, ue->redcap_cap); - drb_t *rrc_drb = get_drb(ue, drb_id); - DevAssert(rrc_drb == est_drb); /* to double check that we create the same which we would retrieve */ + drb_t *rrc_drb = get_drb(&ue->drbs, est_drb->drb_id); + DevAssert(rrc_drb); return rrc_drb; } @@ -229,22 +268,3 @@ NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1) return DRB_config; } - -uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue) -{ - for (uint8_t drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++) - if (ue->established_drbs[drb_id].status == 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; -} - -int get_number_active_drbs(gNB_RRC_UE_t *ue) -{ - int n = 0; - for (int i = 0; i < MAX_DRBS_PER_UE; ++i) - if (ue->established_drbs[i].status != DRB_INACTIVE) - n++; - return n; -} diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.h b/openair2/RRC/NR/rrc_gNB_radio_bearers.h index 0a76c9d796..982e7ea42d 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.h +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.h @@ -28,19 +28,13 @@ #include "e1ap_messages_types.h" #include "nr_rrc_defs.h" -#define DRB_ACTIVE_NONGBR (2) /* DRB is used for Non-GBR Flows */ -#define DRB_ACTIVE (1) -#define DRB_INACTIVE (0) -#define GBR_FLOW (1) -#define NONGBR_FLOW (0) - /// @brief Generates an ASN1 DRB-ToAddMod, from the established_drbs in gNB_RRC_UE_t. /// @param drb_t drb_asn1 /// @return Returns the ASN1 DRB-ToAddMod structs. NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1); /// @brief retrieve the data structure representing DRB with ID drb_id of UE ue -drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id); +drb_t *get_drb(seq_arr_t *seq, int id); /// @brief Creates and stores a DRB in the gNB_RRC_UE_t struct /// @param ue The gNB_RRC_UE_t struct that holds information for the UEs @@ -52,19 +46,12 @@ drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id); /// @param pdcp_config /// @return returns a pointer to the generated DRB structure drb_t *generateDRB(gNB_RRC_UE_t *ue, - uint8_t drb_id, const pdusession_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering, const nr_pdcp_configuration_t *pdcp_config); -/// @brief return the next available (inactive) DRB ID of UE ue -uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue); - -/// @brief returns the number of active DRBs for this UE -int get_number_active_drbs(gNB_RRC_UE_t *ue); - /// @brief retrieve PDU session of UE ue with ID id rrc_pdu_session_param_t *find_pduSession(seq_arr_t *seq, int id); @@ -79,4 +66,10 @@ void set_bearer_context_pdcp_config(bearer_context_pdcp_config_t *pdcp_config, d void free_pdusession(void *ptr); +/// @brief Add DRB to RRC list +drb_t *nr_rrc_add_drb(seq_arr_t *drb_ptr, int pdusession_id); + +/// @brief Function to free DRB in RRC +void free_drb(void *ptr); + #endif