From 9da3cbc9ec4b8e0e9056ad1ae41cfdaec49a23f8 Mon Sep 17 00:00:00 2001 From: Melissa Elkadi Date: Tue, 14 Dec 2021 16:17:30 -0800 Subject: [PATCH] Cherry picking UCI multiplexing for CSI reports --- executables/nr-ue.c | 76 ----- nfapi/oai_integration/nfapi_vnf.c | 37 +-- nfapi/open-nFAPI/nfapi/src/nfapi_p7.c | 22 +- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 87 +++++- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 1 + openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 3 +- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 299 ++++++++++++++------ openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h | 2 + 8 files changed, 333 insertions(+), 194 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 2e7b2ea0e1..2cbeaf502c 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -194,69 +194,6 @@ static void L1_nsa_prach_procedures(frame_t frame, int slot, fapi_nr_ul_config_p LOG_D(NR_MAC, "We have successfully filled the rach_ind queue with the recently filled rach ind\n"); } -static bool sfn_slot_matcher(void *wanted, void *candidate) -{ - nfapi_p7_message_header_t *msg = candidate; - int sfn_sf = *(int*)wanted; - - switch (msg->message_id) - { - case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: - { - nfapi_nr_rach_indication_t *ind = candidate; - return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; - } - - case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: - { - nfapi_nr_rx_data_indication_t *ind = candidate; - return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; - } - - case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: - { - nfapi_nr_crc_indication_t *ind = candidate; - return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; - } - - case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: - { - nfapi_nr_uci_indication_t *ind = candidate; - return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; - } - - case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: - { - nfapi_nr_dl_tti_request_t *ind = candidate; - return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; - } - - case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: - { - nfapi_nr_tx_data_request_t *ind = candidate; - return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; - } - - case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: - { - nfapi_nr_ul_dci_request_t *ind = candidate; - return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; - } - - case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: - { - nfapi_nr_ul_tti_request_t *ind = candidate; - return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; - } - - default: - LOG_E(NR_MAC, "sfn_slot_match bad ID: %d\n", msg->message_id); - - } - - return false; -} - static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) { nfapi_nr_rach_indication_t *rach_ind = unqueue_matching(&nr_rach_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot); @@ -265,15 +202,6 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) nfapi_nr_dl_tti_request_t *dl_tti_request = get_queue(&nr_dl_tti_req_queue); nfapi_nr_ul_dci_request_t *ul_dci_request = get_queue(&nr_ul_dci_req_queue); - LOG_D(NR_MAC, "Try to get a ul_tti_req for sfn/slot %d %d from queue with %lu items\n", - NFAPI_SFNSLOT2SFN(mac->nr_ue_emul_l1.active_harq_sfn_slot),NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.active_harq_sfn_slot), nr_ul_tti_req_queue.num_items); - nfapi_nr_ul_tti_request_t *ul_tti_request = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.active_harq_sfn_slot); - if (!ul_tti_request) - { - LOG_D(NR_MAC, "Try to get a ul_tti_req from seprate queue because dl_tti_req was late\n"); - ul_tti_request = unqueue_matching(&nr_wait_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.active_harq_sfn_slot); - } - if (rach_ind && rach_ind->number_of_pdus > 0) { NR_UL_IND_t UL_INFO = { @@ -335,10 +263,6 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) { check_and_process_dci(NULL, NULL, ul_dci_request, NULL); } - if (ul_tti_request && ul_tti_request->n_pdus > 0) - { - check_and_process_dci(NULL, NULL, NULL, ul_tti_request); - } } static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info, NR_PRACH_RESOURCES_t *prach_resources) diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 44ee05940f..0fed6b33d0 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -792,7 +792,7 @@ int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind) uci_ind_pdu->harq->harq_list = CALLOC(uci_ind_pdu->harq->num_harq, sizeof(*uci_ind_pdu->harq->harq_list)); AssertFatal(uci_ind_pdu->harq->harq_list != NULL, "Memory not allocated for uci_ind_pdu->harq->harq_list in phy_nr_uci_indication."); for (int j = 0; j < uci_ind_pdu->harq->num_harq; j++) - uci_ind_pdu->harq->harq_list[j].harq_value = ind_pdu->harq->harq_list[j].harq_value; + uci_ind_pdu->harq->harq_list[j].harq_value = ind_pdu->harq->harq_list[j].harq_value; } break; } @@ -800,21 +800,26 @@ int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind) case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_2_3_4; nfapi_nr_uci_pucch_pdu_format_2_3_4_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_2_3_4; - - uci_ind_pdu->harq.harq_payload = CALLOC(1, sizeof(*uci_ind_pdu->harq.harq_payload)); - AssertFatal(uci_ind_pdu->harq.harq_payload != NULL, "Memory not allocated for uci_ind_pdu->harq.harq_payload in phy_nr_uci_indication."); - *uci_ind_pdu->harq.harq_payload = *ind_pdu->harq.harq_payload; - - - uci_ind_pdu->csi_part1.csi_part1_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part1.csi_part1_payload)); - AssertFatal(uci_ind_pdu->csi_part1.csi_part1_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part1.csi_part1_payload in phy_nr_uci_indication."); - *uci_ind_pdu->csi_part1.csi_part1_payload = *ind_pdu->csi_part1.csi_part1_payload; - - - uci_ind_pdu->csi_part2.csi_part2_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part2.csi_part2_payload)); - AssertFatal(uci_ind_pdu->csi_part2.csi_part2_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part2.csi_part2_payload in phy_nr_uci_indication."); - *uci_ind_pdu->csi_part2.csi_part2_payload = *ind_pdu->csi_part2.csi_part2_payload; - + if (ind_pdu->harq.harq_payload) { + uci_ind_pdu->harq.harq_payload = CALLOC(1, sizeof(*uci_ind_pdu->harq.harq_payload)); + AssertFatal(uci_ind_pdu->harq.harq_payload != NULL, "Memory not allocated for uci_ind_pdu->harq.harq_payload in phy_nr_uci_indication."); + *uci_ind_pdu->harq.harq_payload = *ind_pdu->harq.harq_payload; + } + if (ind_pdu->sr.sr_payload) { + uci_ind_pdu->sr.sr_payload = CALLOC(1, sizeof(*uci_ind_pdu->sr.sr_payload)); + AssertFatal(uci_ind_pdu->sr.sr_payload != NULL, "Memory not allocated for uci_ind_pdu->sr.sr_payload in phy_nr_uci_indication."); + *uci_ind_pdu->sr.sr_payload = *ind_pdu->sr.sr_payload; + } + if (ind_pdu->csi_part1.csi_part1_payload) { + uci_ind_pdu->csi_part1.csi_part1_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part1.csi_part1_payload)); + AssertFatal(uci_ind_pdu->csi_part1.csi_part1_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part1.csi_part1_payload in phy_nr_uci_indication."); + *uci_ind_pdu->csi_part1.csi_part1_payload = *ind_pdu->csi_part1.csi_part1_payload; + } + if (ind_pdu->csi_part2.csi_part2_payload) { + uci_ind_pdu->csi_part2.csi_part2_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part2.csi_part2_payload)); + AssertFatal(uci_ind_pdu->csi_part2.csi_part2_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part2.csi_part2_payload in phy_nr_uci_indication."); + *uci_ind_pdu->csi_part2.csi_part2_payload = *ind_pdu->csi_part2.csi_part2_payload; + } break; } } diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index adc6d6e384..d103200787 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -5906,9 +5906,25 @@ static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *valu return 1; } +static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t* value, + uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_p7_codec_config_t *config) { -static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) { - nfapi_nr_uci_pucch_pdu_format_2_3_4_t* value = (nfapi_nr_uci_pucch_pdu_format_2_3_4_t*) tlv; + if (!pull8(ppReadPackedMsg, &value->pduBitmap, end)) + return 0; + if (!pull32(ppReadPackedMsg, &value->handle, end)) + return 0; + if (!pull16(ppReadPackedMsg, &value->rnti, end)) + return 0; + if (!pull8(ppReadPackedMsg, &value->pucch_format, end)) + return 0; + if (!pull8(ppReadPackedMsg, &value->ul_cqi, end)) + return 0; + if (!pull16(ppReadPackedMsg, &value->timing_advance, end)) + return 0; + if (!pull16(ppReadPackedMsg, &value->rssi, end)) + return 0; if(!(pull8(ppReadPackedMsg, &value->pduBitmap, end) && pull32(ppReadPackedMsg, &value->handle, end) && @@ -5988,7 +6004,7 @@ static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t *value, } case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &value->pucch_pdu_format_2_3_4; - if (!unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end)) + if (!unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end, config)) return 0; break; } diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 4fd337eb09..7798e789a3 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -36,6 +36,7 @@ #include "fapi_nr_ue_l1.h" #include "harq_nr.h" //#include "PHY/phy_vars_nr_ue.h" +#include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h" #include "PHY/defs_nr_UE.h" #include "PHY/impl_defs_nr.h" @@ -50,7 +51,7 @@ queue_t nr_crc_ind_queue; queue_t nr_uci_ind_queue; int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response) { - + NR_UE_MAC_INST_t *mac = get_mac_inst(0); if(scheduled_response != NULL) { if (scheduled_response->ul_config != NULL) @@ -92,10 +93,6 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response rx_ind->pdu_list[j].rnti = pusch_config_pdu->rnti; rx_ind->pdu_list[j].timing_advance = scheduled_response->tx_request->tx_config.timing_advance; rx_ind->pdu_list[j].ul_cqi = scheduled_response->tx_request->tx_config.ul_cqi; - char buffer[1024]; - hexdump(rx_ind->pdu_list[j].pdu, rx_ind->pdu_list[j].pdu_length, buffer, sizeof(buffer)); - LOG_D(NR_MAC, "Hexdump of pdu %s before queuing rx_ind\n", - buffer); } crc_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION; @@ -147,6 +144,84 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response break; } + case FAPI_NR_UL_CONFIG_TYPE_PUCCH: + { + nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind)); + uci_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION; + uci_ind->sfn = scheduled_response->frame; + uci_ind->slot = scheduled_response->slot; + uci_ind->num_ucis = 1; + uci_ind->uci_list = CALLOC(uci_ind->num_ucis, sizeof(*uci_ind->uci_list)); + for (int j = 0; j < uci_ind->num_ucis; j++) + { + if (ul_config->ul_config_list[i].pucch_config_pdu.format_type == 2) + { + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu_2_3_4 = &uci_ind->uci_list[j].pucch_pdu_format_2_3_4; + uci_ind->uci_list[j].pdu_type = NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE; + uci_ind->uci_list[j].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_2_3_4_t); + memset(pdu_2_3_4, 0, sizeof(*pdu_2_3_4)); + pdu_2_3_4->handle = 0; + pdu_2_3_4->rnti = ul_config->ul_config_list[i].pucch_config_pdu.rnti; + pdu_2_3_4->pucch_format = ul_config->ul_config_list[i].pucch_config_pdu.format_type; + pdu_2_3_4->ul_cqi = 255; + pdu_2_3_4->timing_advance = 0; + pdu_2_3_4->rssi = 0; + // TODO: Eventually check 38.212:Sect.631 to know when to use csi_part2, for now only using csi_part1 + pdu_2_3_4->pduBitmap = 4; + pdu_2_3_4->csi_part1.csi_part1_bit_len = ul_config->ul_config_list[i].pucch_config_pdu.nr_of_symbols; + int csi_part1_byte_len = (int)((pdu_2_3_4->csi_part1.csi_part1_bit_len / 8) + 1); + AssertFatal(!pdu_2_3_4->csi_part1.csi_part1_payload, "pdu_2_3_4->csi_part1.csi_part1_payload != NULL\n"); + pdu_2_3_4->csi_part1.csi_part1_payload = CALLOC(csi_part1_byte_len, + sizeof(pdu_2_3_4->csi_part1.csi_part1_payload)); + for (int k = 0; k < csi_part1_byte_len; k++) + { + pdu_2_3_4->csi_part1.csi_part1_payload[k] = (ul_config->ul_config_list[i]. + pucch_config_pdu.payload >> (k * 8)) & 0xff; + } + pdu_2_3_4->csi_part1.csi_part1_crc = 0; + int sfn_slot = NFAPI_SFNSLOT2HEX(uci_ind->sfn, uci_ind->slot); + nfapi_nr_uci_indication_t *queued_uci_ind = unqueue_matching(&nr_uci_ind_queue, + MAX_QUEUE_SIZE, + sfn_slot_matcher, + &sfn_slot); + if (queued_uci_ind) + { + LOG_I(NR_MAC, "There was a matching UCI with sfn %d, slot %d in queue\n", + NFAPI_SFNSLOT2SFN(sfn_slot), NFAPI_SFNSLOT2SLOT(sfn_slot)); + if (queued_uci_ind->uci_list[0].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE) + pdu_2_3_4->pduBitmap = 6; // harq: pduBitmap >> 1, csi: pduBitmap >> 2 + free(queued_uci_ind); + break; + } + } + else + { + nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[j].pucch_pdu_format_0_1; + uci_ind->uci_list[j].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE; + uci_ind->uci_list[j].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t); + memset(pdu_0_1, 0, sizeof(*pdu_0_1)); + pdu_0_1->handle = 0; + pdu_0_1->rnti = ul_config->ul_config_list[i].pucch_config_pdu.rnti; + pdu_0_1->pucch_format = 1; + pdu_0_1->ul_cqi = 255; + pdu_0_1->timing_advance = 0; + pdu_0_1->rssi = 0; + } + } + + LOG_I(NR_PHY, "In %s: Filled queue uci_ind_234 which was filled by ulconfig.\n" + "uci_num %d, SFN/SLOT: [%d, %d]\n", + __FUNCTION__, uci_ind->num_ucis, uci_ind->sfn, uci_ind->slot); + + if (!put_queue(&nr_uci_ind_queue, uci_ind)) + { + LOG_E(NR_MAC, "Put_queue failed for uci_ind\n"); + free(uci_ind->uci_list); + free(uci_ind); + } + break; + } + default: LOG_I(NR_MAC, "Unknown ul_config->pdu_type %d\n", pdu_type); break; @@ -173,7 +248,7 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind)); uci_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION; uci_ind->sfn = scheduled_response->frame; - uci_ind->slot = scheduled_response->slot; + uci_ind->slot = NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.active_harq_sfn_slot); uci_ind->num_ucis = 1; uci_ind->uci_list = CALLOC(uci_ind->num_ucis, sizeof(*uci_ind->uci_list)); for (int j = 0; j < uci_ind->num_ucis; j++) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index ba3128923f..2b2181177d 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -272,6 +272,7 @@ typedef struct { bool expected_dci; bool index_has_dci[16]; int active_harq_sfn_slot; + int active_uci_sfn_slot; } nr_emulated_l1_t; typedef struct { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 22a13d223b..4bc074df56 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2183,6 +2183,7 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu; fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH); + mac->nr_ue_emul_l1.active_uci_sfn_slot = NFAPI_SFNSLOT2HEX(frameP, slotP); pthread_mutex_unlock(&ul_config->mutex_ul_config); nr_ue_configure_pucch(mac, @@ -2191,7 +2192,7 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in pucch, pucch_pdu, O_SR, O_ACK, O_CSI); - LOG_D(NR_MAC,"Configuring pucch, is_common = %d\n",pucch->is_common); + LOG_I(NR_MAC,"Configuring pucch, is_common = %d and format %d\n",pucch->is_common, pucch_pdu->format_type); nr_scheduled_response_t scheduled_response; fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index b98a9c8789..805c2dd2a8 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -217,6 +217,69 @@ void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id) } } +bool sfn_slot_matcher(void *wanted, void *candidate) +{ + nfapi_p7_message_header_t *msg = candidate; + int sfn_sf = *(int*)wanted; + + switch (msg->message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: + { + nfapi_nr_rach_indication_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: + { + nfapi_nr_rx_data_indication_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: + { + nfapi_nr_crc_indication_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: + { + nfapi_nr_uci_indication_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + { + nfapi_nr_dl_tti_request_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: + { + nfapi_nr_tx_data_request_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: + { + nfapi_nr_ul_dci_request_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: + { + nfapi_nr_ul_tti_request_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; + } + + default: + LOG_E(NR_MAC, "sfn_slot_match bad ID: %d\n", msg->message_id); + + } + + return false; +} + static void fill_dl_info_with_pdcch(fapi_nr_dci_indication_t *dci, nfapi_nr_dl_dci_pdu_t *rx_dci, int idx) { int num_bytes = (rx_dci->PayloadSizeBits + 7) / 8; @@ -460,6 +523,38 @@ static void copy_tx_data_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi dl_info->rx_ind->number_pdus = pdu_idx; } +static void free_uci_inds(nfapi_nr_uci_indication_t *uci_ind) +{ + for (int k = 0; k < uci_ind->num_ucis; k++) + { + if (uci_ind->uci_list[k].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE) + { + nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[k].pucch_pdu_format_0_1; + free(pdu_0_1->sr); + pdu_0_1->sr = NULL; + if (pdu_0_1->harq) + { + free(pdu_0_1->harq->harq_list); + pdu_0_1->harq->harq_list = NULL; + } + free(pdu_0_1->harq); + pdu_0_1->harq = NULL; + } + if (uci_ind->uci_list[k].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE) + { + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu_2_3_4 = &uci_ind->uci_list[k].pucch_pdu_format_2_3_4; + free(pdu_2_3_4->sr.sr_payload); + pdu_2_3_4->sr.sr_payload = NULL; + free(pdu_2_3_4->harq.harq_payload); + pdu_2_3_4->harq.harq_payload = NULL; + } + } + free(uci_ind->uci_list); + uci_ind->uci_list = NULL; + free(uci_ind); + uci_ind = NULL; +} + static void copy_ul_dci_data_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_nr_ul_dci_request_t *ul_dci_req) { NR_UE_MAC_INST_t *mac = get_mac_inst(dl_info->module_id); @@ -503,31 +598,28 @@ static void copy_ul_dci_data_req_to_dl_info(nr_downlink_indication_t *dl_info, n dl_info->slot = ul_dci_req->Slot; } -static nfapi_nr_uci_indication_t *multiplex_uci_ind(NR_UE_MAC_INST_t *mac, int num_active_harqs) +static nfapi_nr_uci_indication_t *multiplex_uci_ind(NR_UE_MAC_INST_t *mac, int sfn_slot) { - AssertFatal(num_active_harqs >= 0, "Invalid value for num_active_harqs %d\n", num_active_harqs); - if (num_active_harqs == 0) - { - return NULL; - } - if (num_active_harqs != nr_uci_ind_queue.num_items) - { - LOG_I(NR_MAC, "The number of active harqs %d doesn't match the number of UCIs in the queue %lu\n", - num_active_harqs, nr_uci_ind_queue.num_items); - return NULL; - } + int num_0_1 = 0; + int num_2_3_4 = 0; + int num_items_in_queue = nr_uci_ind_queue.num_items; nfapi_nr_uci_indication_t *uci_ind = MALLOC(sizeof(*uci_ind)); uci_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION; - uci_ind->sfn = NFAPI_SFNSLOT2SFN(mac->nr_ue_emul_l1.active_harq_sfn_slot); - uci_ind->slot = NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.active_harq_sfn_slot); - uci_ind->num_ucis = num_active_harqs; - uci_ind->uci_list = CALLOC(uci_ind->num_ucis, sizeof(*uci_ind->uci_list)); - for (int i = 0; i < num_active_harqs; i++) + uci_ind->num_ucis = 0; + uci_ind->uci_list = CALLOC(num_items_in_queue, sizeof(*uci_ind->uci_list)); + for (int i = 0; i < num_items_in_queue; i++) { - nfapi_nr_uci_indication_t *queued_uci_ind = get_queue(&nr_uci_ind_queue); - AssertFatal(queued_uci_ind, "There was not a UCI in the queue!\n"); - nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[i].pucch_pdu_format_0_1; + nfapi_nr_uci_indication_t *queued_uci_ind = unqueue_matching(&nr_uci_ind_queue, + MAX_QUEUE_SIZE, + sfn_slot_matcher, + &sfn_slot); + if (!queued_uci_ind) + { + LOG_I(NR_MAC, "There was not a matching UCI with sfn %d, slot %d in queue\n", + NFAPI_SFNSLOT2SFN(sfn_slot), NFAPI_SFNSLOT2SLOT(sfn_slot)); + break; + } /* In openair1/SCHED_NR_UE/fapi_nr_ue_l1.c nr_ue_schedule_response_stub(), the number of UCIs is hard coded to 1. This is why we always use index 0 of the @@ -536,19 +628,51 @@ static nfapi_nr_uci_indication_t *multiplex_uci_ind(NR_UE_MAC_INST_t *mac, int n queued_uci_ind->num_ucis); uci_ind->uci_list[i].pdu_type = queued_uci_ind->uci_list[0].pdu_type; uci_ind->uci_list[i].pdu_size = queued_uci_ind->uci_list[0].pdu_size; + if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE) + { + num_0_1++; + nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[i].pucch_pdu_format_0_1; + nfapi_nr_uci_pucch_pdu_format_0_1_t *queued_pdu_0_1 = &queued_uci_ind->uci_list[0].pucch_pdu_format_0_1; + pdu_0_1->handle = queued_pdu_0_1->handle; + pdu_0_1->rnti = queued_pdu_0_1->rnti; + pdu_0_1->pucch_format = queued_pdu_0_1->pucch_format; + pdu_0_1->ul_cqi = queued_pdu_0_1->ul_cqi; + pdu_0_1->timing_advance = queued_pdu_0_1->timing_advance; + pdu_0_1->rssi = queued_pdu_0_1->rssi; + } + if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE) + { + num_2_3_4++; + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu_2_3_4 = &uci_ind->uci_list[i].pucch_pdu_format_2_3_4; + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *queued_pdu_2_3_4 = &queued_uci_ind->uci_list[0].pucch_pdu_format_2_3_4; + pdu_2_3_4->handle = queued_pdu_2_3_4->handle; + pdu_2_3_4->rnti = queued_pdu_2_3_4->rnti; + pdu_2_3_4->pucch_format = queued_pdu_2_3_4->pucch_format; + pdu_2_3_4->ul_cqi = queued_pdu_2_3_4->ul_cqi; + pdu_2_3_4->timing_advance = queued_pdu_2_3_4->timing_advance; + pdu_2_3_4->rssi = queued_pdu_2_3_4->rssi; + pdu_2_3_4->pduBitmap = queued_pdu_2_3_4->pduBitmap; + pdu_2_3_4->csi_part1.csi_part1_bit_len = queued_pdu_2_3_4->csi_part1.csi_part1_bit_len; + AssertFatal(!pdu_2_3_4->csi_part1.csi_part1_payload, "pdu_2_3_4->csi_part1.csi_part1_payload != NULL\n"); + pdu_2_3_4->csi_part1.csi_part1_payload = CALLOC((int)((pdu_2_3_4->csi_part1.csi_part1_bit_len / 8) + 1), + sizeof(pdu_2_3_4->csi_part1.csi_part1_payload)); + memcpy(pdu_2_3_4->csi_part1.csi_part1_payload, queued_pdu_2_3_4->csi_part1.csi_part1_payload, + sizeof(*queued_pdu_2_3_4->csi_part1.csi_part1_payload)); + } + uci_ind->num_ucis = num_2_3_4 + num_0_1; - nfapi_nr_uci_pucch_pdu_format_0_1_t *queued_pdu_0_1 = &queued_uci_ind->uci_list[0].pucch_pdu_format_0_1; - pdu_0_1->handle = queued_pdu_0_1->handle; - pdu_0_1->rnti = queued_pdu_0_1->rnti; - pdu_0_1->pucch_format = queued_pdu_0_1->pucch_format; - pdu_0_1->ul_cqi = queued_pdu_0_1->ul_cqi; - pdu_0_1->timing_advance = queued_pdu_0_1->timing_advance; - pdu_0_1->rssi = queued_pdu_0_1->rssi; free(queued_uci_ind->uci_list); queued_uci_ind->uci_list = NULL; free(queued_uci_ind); queued_uci_ind = NULL; } + + if (num_2_3_4 > 0 && num_0_1 > 0) + { + LOG_E(NR_MAC, "We have a harq ACK/NACK while CSI reporting as seprate UCIs but we shouldn't. " + "We multiplex before queueing the UCI!!!\n"); + abort(); + } return uci_ind; } @@ -556,6 +680,7 @@ static void copy_ul_tti_data_req_to_dl_info(nr_downlink_indication_t *dl_info, n { NR_UE_MAC_INST_t *mac = get_mac_inst(dl_info->module_id); int num_pdus = ul_tti_req->n_pdus; + int sfn_slot = NFAPI_SFNSLOT2HEX(ul_tti_req->SFN, ul_tti_req->Slot); AssertFatal(num_pdus >= 0, "Invalid ul_tti_request number of PDUS\n"); AssertFatal(num_pdus <= sizeof(ul_tti_req->pdus_list) / sizeof(ul_tti_req->pdus_list[0]), "Too many pdus %d in ul_tti_req\n", num_pdus); @@ -570,38 +695,67 @@ static void copy_ul_tti_data_req_to_dl_info(nr_downlink_indication_t *dl_info, n { AssertFatal(nr_uci_ind_queue.num_items >= 0, "Invalid num_items in UCI_ind queue %lu\n", nr_uci_ind_queue.num_items); - int num_active_harqs = pdu_list->pucch_pdu.bit_len_harq; - LOG_I(NR_MAC, "The number of active harqs %d from ul_tti_req\n", num_active_harqs); - nfapi_nr_uci_indication_t *uci_ind = multiplex_uci_ind(mac, num_active_harqs); + + nfapi_nr_uci_indication_t *uci_ind = multiplex_uci_ind(mac, sfn_slot); if (uci_ind && uci_ind->num_ucis > 0) { - LOG_D(NR_MAC, "This is the SFN/SF [%d, %d] and RNTI %x of the UCI ind. ul_tti_req.pdu[%d]->rnti = %x \n", - uci_ind->sfn, uci_ind->slot, uci_ind->uci_list[0].pucch_pdu_format_0_1.rnti, i, ul_tti_req->pdus_list[i].pucch_pdu.rnti); uci_ind->sfn = ul_tti_req->SFN; uci_ind->slot = ul_tti_req->Slot; + LOG_D(NR_MAC, "This is the SFN/SF [%d, %d] and RNTI %x of the UCI ind. ul_tti_req.pdu[%d]->rnti = %x \n", + uci_ind->sfn, uci_ind->slot, uci_ind->uci_list[0].pucch_pdu_format_0_1.rnti, i, ul_tti_req->pdus_list[i].pucch_pdu.rnti); for (int j = 0; j < uci_ind->num_ucis; j++) { - nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[j].pucch_pdu_format_0_1; - if (pdu_list->pucch_pdu.sr_flag) + if (uci_ind->uci_list[j].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE) { - LOG_D(NR_MAC, "We have the SR flag in pdu i %d\n", i); - pdu_0_1->pduBitmap = 1; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR - pdu_0_1->sr = CALLOC(1, sizeof(*pdu_0_1->sr)); - pdu_0_1->sr->sr_confidence_level = 0; - pdu_0_1->sr->sr_indication = 1; - } - if (pdu_list->pucch_pdu.bit_len_harq > 0) - { - LOG_D(NR_MAC, "We have the Harq len bits %d\n", pdu_list->pucch_pdu.bit_len_harq); - pdu_0_1->pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR - pdu_0_1->harq = CALLOC(1, sizeof(*pdu_0_1->harq)); - pdu_0_1->harq->num_harq = 1; - pdu_0_1->harq->harq_confidence_level = 0; - pdu_0_1->harq->harq_list = CALLOC(pdu_0_1->harq->num_harq, sizeof(*pdu_0_1->harq->harq_list)); - for (int k = 0; k < pdu_0_1->harq->num_harq; k++) + nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[j].pucch_pdu_format_0_1; + if (pdu_list->pucch_pdu.sr_flag) { - pdu_0_1->harq->harq_list[k].harq_value = 0; + pdu_0_1->pduBitmap = 1; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR + pdu_0_1->sr = CALLOC(1, sizeof(*pdu_0_1->sr)); + pdu_0_1->sr->sr_confidence_level = 0; + pdu_0_1->sr->sr_indication = 1; + } + if (pdu_list->pucch_pdu.bit_len_harq > 0) + { + pdu_0_1->pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR + pdu_0_1->harq = CALLOC(1, sizeof(*pdu_0_1->harq)); + pdu_0_1->harq->num_harq = 1; + pdu_0_1->harq->harq_confidence_level = 0; + pdu_0_1->harq->harq_list = CALLOC(pdu_0_1->harq->num_harq, sizeof(*pdu_0_1->harq->harq_list)); + for (int k = 0; k < pdu_0_1->harq->num_harq; k++) + { + pdu_0_1->harq->harq_list[k].harq_value = 0; + } + } + } + if (uci_ind->uci_list[j].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE) + { + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu_2_3_4 = &uci_ind->uci_list[j].pucch_pdu_format_2_3_4; + if (pdu_list->pucch_pdu.sr_flag) + { + pdu_2_3_4->pduBitmap = 5; + pdu_2_3_4->sr.sr_bit_len = 0; + AssertFatal(!pdu_2_3_4->sr.sr_payload, "pdu_2_3_4->sr.sr_payload != NULL\n"); + pdu_2_3_4->sr.sr_payload = CALLOC((int)((pdu_2_3_4->sr.sr_bit_len / 8) + 1), + sizeof(*pdu_2_3_4->sr.sr_payload)); + } + if (pdu_list->pucch_pdu.bit_len_harq > 0) + { + if (pdu_list->pucch_pdu.sr_flag) + { + pdu_2_3_4->pduBitmap = 7; + } + pdu_2_3_4->harq.harq_bit_len = pdu_list->pucch_pdu.bit_len_harq; + LOG_D(NR_MAC, "This is bit_len_harq %d and pdu_2_3_4->pduBitmap %d\n", + pdu_list->pucch_pdu.bit_len_harq, pdu_2_3_4->pduBitmap); + pdu_2_3_4->harq.harq_crc = 0; + AssertFatal(!pdu_2_3_4->harq.harq_payload, "pdu_2_3_4->harq.harq_payload != NULL\n"); + pdu_2_3_4->harq.harq_payload = CALLOC((int)((pdu_2_3_4->harq.harq_bit_len / 8) + 1), + sizeof(*pdu_2_3_4->harq.harq_payload)); + /* TODO: Later, when abstracting, we can set particular bits in the + payload to 0 to indicate a NACK. For now, we memset all bits to 1. */ + memset(pdu_2_3_4->harq.harq_payload, 0xff, sizeof(*pdu_2_3_4->harq.harq_payload)); } } } @@ -612,27 +766,7 @@ static void copy_ul_tti_data_req_to_dl_info(nr_downlink_indication_t *dl_info, n }; send_nsa_standalone_msg(&UL_INFO, uci_ind->header.message_id); sent_uci = true; - - for (int k = 0; k < uci_ind->num_ucis; k++) - { - nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[k].pucch_pdu_format_0_1; - if (pdu_list->pucch_pdu.sr_flag) - { - free(pdu_0_1->sr); - pdu_0_1->sr = NULL; - } - if (pdu_list->pucch_pdu.bit_len_harq > 1) - { - free(pdu_0_1->harq->harq_list); - pdu_0_1->harq->harq_list = NULL; - free(pdu_0_1->harq); - pdu_0_1->harq = NULL; - } - } - free(uci_ind->uci_list); - uci_ind->uci_list = NULL; - free(uci_ind); - uci_ind = NULL; + free_uci_inds(uci_ind); } } } @@ -890,28 +1024,9 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea } LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST message in SFN/slot %d %d.\n", ul_tti_request->SFN, ul_tti_request->Slot); - if (nr_uci_ind_queue.num_items > 0) //TODO: In the future UL_TTIs can be for ULSCH and SRS. + if (ul_tti_request && ul_tti_request->n_pdus > 0) { - LOG_D(NR_MAC, "We added UL_TTI_REQ to queue for sfn slot %d %d\n", - ul_tti_request->SFN, ul_tti_request->Slot); - if (!put_queue(&nr_ul_tti_req_queue, ul_tti_request)) - { - LOG_E(NR_PHY, "put_queue failed for ul_tti_request.\n"); - free(ul_tti_request); - ul_tti_request = NULL; - } - } - /* TODO: This indicates that dl_tti_req was late or never arrived. If there are - not any prepared uci indications, the NRUE likely never had time to - populate the message is the dl_tti_req came in late and we received a - ul_tti_req immediately after the dl_tti_request. This is an attempt to - mitigate proxy timing issues. */ - else if (nr_uci_ind_queue.num_items == 0) - { - LOG_D(NR_MAC, "We added UL_TTI_REQ to queue for sfn slot %d %d\n", - ul_tti_request->SFN, ul_tti_request->Slot); - nfapi_nr_ul_tti_request_t *evicted_ul_tti_req = put_queue_replace(&nr_wait_ul_tti_req_queue, ul_tti_request); - free(evicted_ul_tti_req); + check_and_process_dci(NULL, NULL, NULL, ul_tti_request); } break; } diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 2a8a514769..039b919b12 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -240,6 +240,8 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, nfapi_nr_ul_dci_request_t *ul_dci_request, nfapi_nr_ul_tti_request_t *ul_tti_request); +bool sfn_slot_matcher(void *wanted, void *candidate); + /**\brief done free of memory allocation by module_id and release to pointer pool. \param module_id module id*/ int nr_ue_if_module_kill(uint32_t module_id);