diff --git a/common/utils/ds/byte_array.c b/common/utils/ds/byte_array.c index 78e1ef4e31..d6ad97e324 100644 --- a/common/utils/ds/byte_array.c +++ b/common/utils/ds/byte_array.c @@ -72,3 +72,17 @@ byte_array_t cp_str_to_ba(const char* str) return dst; } + +char* cp_ba_to_str(const byte_array_t ba) +{ + assert(ba.len > 0); + + const size_t sz = ba.len; + char* str = calloc(sz+1, sizeof(char)); + assert(str != NULL && "Memory exhausted"); + + memcpy(str, ba.buf, sz); + str[sz] = '\0'; + + return str; +} diff --git a/common/utils/ds/byte_array.h b/common/utils/ds/byte_array.h index 236f3e683f..18adb33047 100644 --- a/common/utils/ds/byte_array.h +++ b/common/utils/ds/byte_array.h @@ -42,5 +42,6 @@ void free_byte_array(byte_array_t ba); bool eq_byte_array(const byte_array_t* m0, const byte_array_t* m1); byte_array_t cp_str_to_ba(const char* str); +char* cp_ba_to_str(const byte_array_t ba); #endif diff --git a/openair2/E2AP/RAN_FUNCTION/CMakeLists.txt b/openair2/E2AP/RAN_FUNCTION/CMakeLists.txt index 1d47f029d9..578bf489df 100644 --- a/openair2/E2AP/RAN_FUNCTION/CMakeLists.txt +++ b/openair2/E2AP/RAN_FUNCTION/CMakeLists.txt @@ -12,7 +12,7 @@ add_library(e2_ran_func_cuup STATIC ../flexric/test/rnd/fill_rnd_data_tc.c ) -target_link_libraries(e2_ran_func_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj sm_common_ie_obj) +target_link_libraries(e2_ran_func_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj sm_common_ie_obj ds) target_compile_definitions(e2_ran_func_cuup PUBLIC ${E2AP_VERSION} ${KPM_VERSION} NGRAN_GNB_CUUP) @@ -35,7 +35,7 @@ add_library(e2_ran_func_du_cucp_cuup STATIC ../flexric/test/rnd/fill_rnd_data_tc.c ) -target_link_libraries(e2_ran_func_du_cucp_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj e2sm_rc_ir_obj sm_common_ie_obj) +target_link_libraries(e2_ran_func_du_cucp_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj e2sm_rc_ir_obj sm_common_ie_obj ds) target_compile_definitions(e2_ran_func_du_cucp_cuup PUBLIC ${E2AP_VERSION} ${KPM_VERSION} NGRAN_GNB_DU NGRAN_GNB_CUCP NGRAN_GNB_CUUP) # Current implementation: 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 40371df046..c9620e871f 100644 --- a/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c +++ b/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c @@ -23,6 +23,7 @@ #include "ran_func_kpm_subs.h" #include "ran_e2sm_ue_id.h" +#include "common/utils/ds/byte_array.h" #include "openair2/E1AP/e1ap_common.h" #include "openair2/E2AP/flexric/src/util/time_now_us.h" #include "openair2/F1AP/f1ap_ids.h" diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 7b010ad5bc..6ffdce88f0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -2126,7 +2126,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, harq->tb_size = tb_size; - uint8_t *buf = (uint8_t *) harq->transportBlock; + uint8_t *buf = allocate_transportBlock_buffer(&harq->transportBlock, tb_size); // Bytes to be transmitted if (harq->round == 0) { uint16_t mac_pdu_length = 0; @@ -2206,11 +2206,11 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, } T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->rnti), - T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, harq->tb_size)); + T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock.buf, harq->tb_size)); // DL TX request nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs]; - memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, sizeof(uint8_t) * harq->tb_size); + memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock.buf, sizeof(uint8_t) * harq->tb_size); tx_req->PDU_index = pduindex; tx_req->num_TLV = 1; tx_req->TLVs[0].length = harq->tb_size; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index ce5bbfe9fd..48a72b527b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -1280,12 +1280,12 @@ void nr_schedule_ue_spec(module_id_t module_id, UE->rnti, current_harq_pid); T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), - T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock, TBS)); + T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock.buf, TBS)); UE->mac_stats.dl.total_rbs_retx += sched_pdsch->rbSize; gNB_mac->mac_stats.used_prb_aggregate += sched_pdsch->rbSize; } else { /* initial transmission */ LOG_D(NR_MAC, "Initial HARQ transmission in %d.%d\n", frame, slot); - uint8_t *buf = (uint8_t *) harq->transportBlock; + uint8_t *buf = allocate_transportBlock_buffer(&harq->transportBlock, TBS); /* first, write all CEs that might be there */ int written = nr_write_ce_dlsch_pdu(module_id, sched_ctrl, @@ -1420,7 +1420,7 @@ void nr_schedule_ue_spec(module_id_t module_id, } T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), - T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, TBS)); + T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock.buf, TBS)); } const int ntx_req = TX_req->Number_of_PDUs; @@ -1429,7 +1429,7 @@ void nr_schedule_ue_spec(module_id_t module_id, tx_req->num_TLV = 1; tx_req->TLVs[0].length = TBS; tx_req->PDU_length = compute_PDU_length(tx_req->num_TLV, tx_req->TLVs[0].length); - memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, TBS); + memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock.buf, TBS); TX_req->Number_of_PDUs++; TX_req->SFN = frame; TX_req->Slot = slot; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 708337640c..ec243fcd86 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2079,12 +2079,35 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca destroy_nr_list(&sched_ctrl->available_ul_harq); destroy_nr_list(&sched_ctrl->feedback_ul_harq); destroy_nr_list(&sched_ctrl->retrans_ul_harq); + for (int i = 0; i < NR_MAX_HARQ_PROCESSES; ++i) + free_transportBlock_buffer(&sched_ctrl->harq_processes[i].transportBlock); free_sched_pucch_list(sched_ctrl); uid_linear_allocator_free(uia, UE->uid); LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti); free(UE); } +#define TB_SINGLE_LAYER (32 * 1024) +uint8_t *allocate_transportBlock_buffer(byte_array_t *tb, uint32_t needed) +{ + DevAssert(needed > 0); + if (tb->buf != NULL && needed <= tb->len) + return tb->buf; // nothing to do, current is enough + + uint32_t size = TB_SINGLE_LAYER; + while (needed > size) + size *= 2; + LOG_D(NR_MAC, "allocating new TB block of size %d\n", size); + free(tb->buf); + tb->buf = malloc_or_fail(size); + tb->len = size; + return tb->buf; +} + +void free_transportBlock_buffer(byte_array_t *tb) +{ + free_byte_array(*tb); +} void set_max_fb_time(NR_UE_UL_BWP_t *UL_BWP, const NR_UE_DL_BWP_t *DL_BWP) { diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index d8c876439b..46deef46e8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -381,6 +381,9 @@ void handle_nr_ul_harq(const int CC_idP, sub_frame_t slot, const nfapi_nr_crc_t *crc_pdu); +uint8_t *allocate_transportBlock_buffer(byte_array_t *tb, uint32_t needed); +void free_transportBlock_buffer(byte_array_t *tb); + void handle_nr_srs_measurements(const module_id_t module_id, const frame_t frame, const sub_frame_t slot, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index c94f64dfef..bb1fba0fe8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -44,6 +44,7 @@ #include #include "common/utils/ds/seq_arr.h" #include "common/utils/nr/nr_common.h" +#include "common/utils/ds/byte_array.h" #define NR_SCHED_LOCK(lock) \ do { \ @@ -481,10 +482,9 @@ typedef struct NR_UE_harq { uint16_t feedback_frame; uint16_t feedback_slot; - /* Transport block to be sent using this HARQ process, its size is in - * sched_pdsch */ - uint32_t transportBlock[38016]; // valid up to 4 layers - uint32_t tb_size; + /* Transport block to be sent using this HARQ process */ + byte_array_t transportBlock; + uint32_t tb_size; // size of currently stored TB /// sched_pdsch keeps information on MCS etc used for the initial transmission NR_sched_pdsch_t sched_pdsch;