diff --git a/CMakeLists.txt b/CMakeLists.txt index 569aae3975..345ae47c62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1458,6 +1458,7 @@ add_library(L2_NR ${MAC_NR_SRC} ${GNB_APP_SRC} ) +target_link_libraries(L2_NR PRIVATE ds alg) add_library(e1_if ${NR_RRC_DIR}/cucp_cuup_direct.c diff --git a/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c b/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c index 0fc0ff82ac..748b4f7d29 100644 --- a/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c +++ b/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c @@ -284,9 +284,9 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst UE_iterator (RC.nrmac[0]->UE_info.list, ue) { NR_UE_sched_ctrl_t *sched_ctrl = &ue->UE_sched_ctrl; // UE matches if any of its DRBs matches - for (int l = 0; l < sched_ctrl->dl_lc_num; ++l) { - long lcid = sched_ctrl->dl_lc_ids[l]; - if (nssai_matches(sched_ctrl->dl_lc_nssai[lcid], sst, sd)) { + for (size_t l = 0; l < seq_arr_size(&sched_ctrl->lc_config); ++l) { + const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, l); + if (nssai_matches(c->nssai, sst, sd)) { if (node_type == ngran_gNB_DU) { f1_ue_data_t rrc_ue_id = du_get_f1_ue_data(ue->rnti); // gNB CU UE ID = rrc_ue_id arr_ue_id.ue_id[arr_ue_id.sz] = fill_ue_id_data[ngran_gNB_DU](NULL, rrc_ue_id.secondary_ue, 0); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 29c1f2ce83..98978553e6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -52,6 +52,8 @@ #include "executables/softmodem-common.h" #include +#include "common/utils/alg/find.h" + extern RAN_CONTEXT_t RC; //extern int l2_init_gNB(void); extern uint8_t nfapi_mode; @@ -272,41 +274,30 @@ static void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddMo { if (rlc_bearer2release_list) { for (int i = 0; i < rlc_bearer2release_list->list.count; i++) { - for (int idx = 0; idx < sched_ctrl->dl_lc_num; idx++) { - if (sched_ctrl->dl_lc_ids[idx] == *rlc_bearer2release_list->list.array[i]) { - const int remaining_lcs = sched_ctrl->dl_lc_num - idx - 1; - memmove(&sched_ctrl->dl_lc_ids[idx], &sched_ctrl->dl_lc_ids[idx + 1], sizeof(sched_ctrl->dl_lc_ids[idx]) * remaining_lcs); - sched_ctrl->dl_lc_num--; - break; - } - } + nr_lc_config_t c = {.lcid = *rlc_bearer2release_list->list.array[i]}; + elm_arr_t elm = find_if(&sched_ctrl->lc_config, &c, eq_lcid_config); + if (elm.found) + seq_arr_erase(&sched_ctrl->lc_config, elm.it); + else + LOG_E(NR_MAC, "could not remove rlc bearer: could not find bearer with ID %d\n", c.lcid); } } if (rlc_bearer2add_list) { // keep lcids for (int i = 0; i < rlc_bearer2add_list->list.count; i++) { - const int lcid = rlc_bearer2add_list->list.array[i]->logicalChannelIdentity; - bool found = false; - for (int idx = 0; idx < sched_ctrl->dl_lc_num; idx++) { - if (sched_ctrl->dl_lc_ids[idx] == lcid) { - found = true; - break; - } - } - - if (!found) { - sched_ctrl->dl_lc_num++; - sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num - 1] = lcid; - LOG_D(NR_MAC, "Adding LCID %d (%s %d)\n", lcid, lcid < 4 ? "SRB" : "DRB", lcid); + nr_lc_config_t c = {.lcid = rlc_bearer2add_list->list.array[i]->logicalChannelIdentity}; + elm_arr_t elm = find_if(&sched_ctrl->lc_config, &c, eq_lcid_config); + if (!elm.found) { + LOG_D(NR_MAC, "Adding LCID %d (%s %d)\n", c.lcid, c.lcid < 4 ? "SRB" : "DRB", c.lcid); + seq_arr_push_back(&sched_ctrl->lc_config, &c, sizeof(c)); + } else { + LOG_W(NR_MAC, "cannot add LCID %d: already present\n", c.lcid); } } } - LOG_D(NR_MAC, "In %s: total num of active bearers %d) \n", - __FUNCTION__, - sched_ctrl->dl_lc_num); - + LOG_D(NR_MAC, "total num of active bearers %ld\n", seq_arr_size(&sched_ctrl->lc_config)); } void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_info_t *UE) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 422ae13d89..ca6d44d5b0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -329,8 +329,9 @@ static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_fram /* loop over all activated logical channels */ // Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH - for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) { - const int lcid = sched_ctrl->dl_lc_ids[i]; + for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); ++i) { + const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i); + const int lcid = c->lcid; const uint16_t rnti = UE->rnti; LOG_D(NR_MAC, "In %s: UE %x: LCID %d\n", __FUNCTION__, rnti, lcid); if (lcid == DL_SCH_LCID_DTCH && sched_ctrl->rrc_processing_timer > 0) { @@ -1275,8 +1276,9 @@ void nr_schedule_ue_spec(module_id_t module_id, if (sched_ctrl->num_total_bytes > 0) { /* loop over all activated logical channels */ - for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) { - const int lcid = sched_ctrl->dl_lc_ids[i]; + for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); ++i) { + const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i); + const int lcid = c->lcid; if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0) continue; // no data for this LC tbs_size_t len = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index a604e13c25..3eb9a9ce7b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -104,9 +104,9 @@ void nr_preprocessor_phytest(module_id_t module_id, } sched_ctrl->num_total_bytes = 0; - sched_ctrl->dl_lc_num = 1; - const int lcid = DL_SCH_LCID_DTCH; - sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num - 1] = lcid; + DevAssert(seq_arr_size(&sched_ctrl->lc_config) == 1); + const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, 0); + const int lcid = c->lcid; const uint16_t rnti = UE->rnti; /* update sched_ctrl->num_total_bytes so that postprocessor schedules data, * if available */ diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index ee0aee0718..d26f8a6a4d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2097,6 +2097,7 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->reconfigCellGroup); ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + seq_arr_free(&sched_ctrl->lc_config, NULL); destroy_nr_list(&sched_ctrl->available_dl_harq); destroy_nr_list(&sched_ctrl->feedback_dl_harq); destroy_nr_list(&sched_ctrl->retrans_dl_harq); @@ -2490,6 +2491,9 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf sched_ctrl->sched_srs.frame = -1; sched_ctrl->sched_srs.slot = -1; + // initialize LCID structure + seq_arr_init(&sched_ctrl->lc_config, sizeof(nr_lc_config_t)); + // initialize UE BWP information NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; memset(dl_bwp, 0, sizeof(*dl_bwp)); @@ -3220,3 +3224,10 @@ long get_lcid_from_srbid(int srb_id) { return srb_id; } + +bool eq_lcid_config(const void *vval, const void *vit) +{ + const nr_lc_config_t *val = (const nr_lc_config_t *)vval; + const nr_lc_config_t *it = (const nr_lc_config_t *)vit; + return it->lcid == val->lcid; +} diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index a4adfd4b08..d0e47075b1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -443,4 +443,6 @@ void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ct void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE); +bool eq_lcid_config(const void *vval, const void *vit); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index a7d1a921eb..492e90d575 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -28,6 +28,7 @@ #include "F1AP_CauseRadioNetwork.h" #include "openair3/ocp-gtpu/gtp_itf.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h" +#include "common/utils/alg/find.h" #include "uper_decoder.h" #include "uper_encoder.h" @@ -318,9 +319,13 @@ static void set_nssaiConfig(const int drb_len, const f1ap_drb_to_be_setup_t *req for (int i = 0; i < drb_len; i++) { const f1ap_drb_to_be_setup_t *drb = &req_drbs[i]; - long lcid = get_lcid_from_drbid(drb->drb_id); - sched_ctrl->dl_lc_nssai[lcid] = drb->nssai; - LOG_I(NR_MAC, "Setting NSSAI sst: %d, sd: %d for DRB: %ld\n", drb->nssai.sst, drb->nssai.sd, drb->drb_id); + nr_lc_config_t c = {.lcid = get_lcid_from_drbid(drb->drb_id)}; + elm_arr_t elm = find_if(&sched_ctrl->lc_config, &c, eq_lcid_config); + if (elm.found) { + nr_lc_config_t *c = (nr_lc_config_t *)elm.it; + c->nssai = drb->nssai; + LOG_I(NR_MAC, "Setting NSSAI sst: %d, sd: %d for DRB: %ld\n", drb->nssai.sst, drb->nssai.sd, drb->drb_id); + } } } @@ -335,8 +340,11 @@ static void set_QoSConfig(const f1ap_ue_context_modif_req_t *req, NR_UE_sched_ct for (int i = 0; i < drb_count; i++) { f1ap_drb_to_be_setup_t *drb_p = &req->drbs_to_be_setup[i]; uint8_t nb_qos_flows = drb_p->drb_info.flows_to_be_setup_length; - long drb_id = drb_p->drb_id; - LOG_I(NR_MAC, "number of QOS flows mapped to DRB_id %ld: %d\n", drb_id, nb_qos_flows); + nr_lc_config_t c = {.lcid = get_lcid_from_drbid(drb_p->drb_id)}; + elm_arr_t elm = find_if(&sched_ctrl->lc_config, &c, eq_lcid_config); + DevAssert(elm.found); + nr_lc_config_t *lc_config = (nr_lc_config_t *) elm.it; + LOG_I(NR_MAC, "number of QOS flows mapped to LCID %d: %d\n", c.lcid, nb_qos_flows); for (int q = 0; q < nb_qos_flows; q++) { f1ap_flows_mapped_to_drb_t *qos_flow = &drb_p->drb_info.flows_mapped_to_drb[q]; @@ -355,14 +363,9 @@ static void set_QoSConfig(const f1ap_ue_context_modif_req_t *req, NR_UE_sched_ct priority = qos_priority[id]; } } - sched_ctrl->qos_config[drb_id - 1][q].fiveQI = fiveqi; - sched_ctrl->qos_config[drb_id - 1][q].priority = priority; - LOG_D(NR_MAC, - "In %s: drb_id %ld: 5QI %lu priority %lu\n", - __func__, - drb_id, - sched_ctrl->qos_config[drb_id - 1][q].fiveQI, - sched_ctrl->qos_config[drb_id - 1][q].priority); + lc_config->qos_config[q].fiveQI = fiveqi; + lc_config->qos_config[q].priority = priority; + LOG_D(NR_MAC, "LC ID %d: 5QI %lu priority %lu\n", c.lcid, fiveqi, priority); } } } @@ -684,8 +687,10 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) UE->expect_reconfiguration = false; /* Re-establish RLC for all remaining bearers */ if (UE->reestablish_rlc) { - for (int i = 1; i < UE->UE_sched_ctrl.dl_lc_num; ++i) - nr_rlc_reestablish_entity(dl_rrc->gNB_DU_ue_id, UE->UE_sched_ctrl.dl_lc_ids[i]); + for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) { + nr_lc_config_t *lc_config = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i); + nr_rlc_reestablish_entity(dl_rrc->gNB_DU_ue_id, lc_config->lcid); + } UE->reestablish_rlc = false; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 320aa273b7..61b833f491 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -170,15 +170,15 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset "UE %04x: MAC: TX %14"PRIu64" RX %14"PRIu64" bytes\n", UE->rnti, stats->dl.total_bytes, stats->ul.total_bytes); - for (int i = 0; i < sched_ctrl->dl_lc_num; i++) { - int lc_id = sched_ctrl->dl_lc_ids[i]; + for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); i++) { + const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i); output += snprintf(output, end - output, "UE %04x: LCID %d: TX %14"PRIu64" RX %14"PRIu64" bytes\n", UE->rnti, - lc_id, - stats->dl.lc_bytes[lc_id], - stats->ul.lc_bytes[lc_id]); + c->lcid, + stats->dl.lc_bytes[c->lcid], + stats->ul.lc_bytes[c->lcid]); } } NR_SCHED_UNLOCK(&gNB->UE_info.mutex); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 0f20b246c6..4e001a035f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -42,6 +42,7 @@ #include #include #include +#include "common/utils/ds/seq_arr.h" #define NR_SCHED_LOCK(lock) \ do { \ @@ -519,6 +520,14 @@ typedef struct NR_QoS_config_s { uint64_t priority; } NR_QoS_config_t; +typedef struct nr_lc_config { + uint8_t lcid; + /// associated NSSAI for DRB + nssai_t nssai; + /// QoS config for DRB + NR_QoS_config_t qos_config[NR_MAX_NUM_QFI]; +} nr_lc_config_t; + /*! \brief scheduling control information set through an API */ #define MAX_CSI_REPORTS 48 typedef struct { @@ -607,20 +616,15 @@ typedef struct { /// UL HARQ processes that await retransmission NR_list_t retrans_ul_harq; NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl; // MAC CE related information - /// number of active DL LCs - uint8_t dl_lc_num; - /// order in which DLSCH scheduler should allocate LCs - uint8_t dl_lc_ids[NR_MAX_NUM_LCID]; /// Timer for RRC processing procedures uint32_t rrc_processing_timer; /// sri, ul_ri and tpmi based on SRS nr_srs_feedback_t srs_feedback; - nssai_t dl_lc_nssai[NR_MAX_NUM_LCID]; - // Information about the QoS configuration for each LCID/DRB - NR_QoS_config_t qos_config[NR_MAX_NUM_LCID - 4][NR_MAX_NUM_QFI]; // 0 -CCCH and 1- 3 SRBs(0,1,2) + /// per-LC configuration + seq_arr_t lc_config; } NR_UE_sched_ctrl_t; typedef struct {