diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 2297f6bf25..fc69cf2722 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -30,6 +30,7 @@ #include "executables/softmodem-common.h" #include "LAYER2/nr_pdcp/nr_pdcp_entity.h" #include "SCHED_NR_UE/pucch_uci_ue_nr.h" +#include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h" /* * NR SLOT PROCESSING SEQUENCE @@ -224,6 +225,30 @@ static bool sfn_slot_matcher(void *wanted, void *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); @@ -232,6 +257,125 @@ static bool sfn_slot_matcher(void *wanted, void *candidate) 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); + nfapi_nr_rx_data_indication_t *rx_ind = unqueue_matching(&nr_rx_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot); + nfapi_nr_crc_indication_t *crc_ind = unqueue_matching(&nr_crc_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &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->active_harq_sfn_slot),NFAPI_SFNSLOT2SLOT(mac->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->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->active_harq_sfn_slot); + } + + if (rach_ind && rach_ind->number_of_pdus > 0) + { + NR_UL_IND_t UL_INFO = { + .rach_ind = *rach_ind, + }; + send_nsa_standalone_msg(&UL_INFO, rach_ind->header.message_id); + for (int i = 0; i < rach_ind->number_of_pdus; i++) + { + free(rach_ind->pdu_list[i].preamble_list); + } + free(rach_ind->pdu_list); + free(rach_ind); + nr_Msg1_transmitted(0, 0, NFAPI_SFNSLOT2SFN(sfn_slot), 0); + } + if (crc_ind && crc_ind->number_crcs > 0) + { + NR_UL_IND_t UL_INFO = { + .crc_ind = *crc_ind, + }; + send_nsa_standalone_msg(&UL_INFO, crc_ind->header.message_id); + free(crc_ind->crc_list); + free(crc_ind); + } + if (rx_ind && rx_ind->number_of_pdus > 0) + { + NR_UL_IND_t UL_INFO = { + .rx_ind = *rx_ind, + }; + send_nsa_standalone_msg(&UL_INFO, rx_ind->header.message_id); + free(rx_ind->pdu_list); + free(rx_ind); + } + if (dl_tti_request) + { + int dl_tti_sfn_slot = NFAPI_SFNSLOT2HEX(dl_tti_request->SFN, dl_tti_request->Slot); + nfapi_nr_tx_data_request_t *tx_data_request = unqueue_matching(&nr_tx_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &dl_tti_sfn_slot); + if (!tx_data_request) + { + LOG_E(NR_MAC, "[%d %d] No corresponding tx_data_request for given dl_tti_request sfn/slot\n", + NFAPI_SFNSLOT2SFN(dl_tti_sfn_slot), NFAPI_SFNSLOT2SLOT(dl_tti_sfn_slot)); + save_nr_measurement_info(dl_tti_request); + free(dl_tti_request); + dl_tti_request = NULL; + } + else if (dl_tti_request->dl_tti_request_body.nPDUs > 0 && tx_data_request->Number_of_PDUs > 0) + { + save_nr_measurement_info(dl_tti_request); + check_and_process_dci(dl_tti_request, tx_data_request, NULL, NULL); + } + else + { + AssertFatal(false, "We dont have PDUs in either dl_tti %d or tx_req %d\n", + dl_tti_request->dl_tti_request_body.nPDUs, tx_data_request->Number_of_PDUs); + } + } + if (ul_dci_request && ul_dci_request->numPdus > 0) + { + 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) +{ + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx); + if (!ul_config) + { + LOG_E(NR_MAC, "mac->ul_config is null! \n"); + return; + } + if (mac->ra.ra_state != RA_SUCCEEDED) + { + AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), + "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); + fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; + uint8_t nr_prach = nr_ue_get_rach(prach_resources, + prach_pdu, + ul_info->module_id, + ul_info->cc_id, + ul_info->frame_tx, + ul_info->gNB_index, + ul_info->slot_tx); + if (nr_prach == 1) + { + L1_nsa_prach_procedures(ul_info->frame_tx, ul_info->slot_tx, prach_pdu); + ul_config->number_pdus = 0; + ul_info->ue_sched_mode = SCHED_ALL; + } + else if (nr_prach == 2) + { + LOG_I(NR_PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, ul_info->module_id); + } + else if(nr_prach == 3) + { + LOG_I(NR_PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, ul_info->module_id); + } + } +} + static void *NRUE_phy_stub_standalone_pnf_task(void *arg) { LOG_I(MAC, "Clearing Queues\n"); @@ -239,14 +383,18 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) reset_queue(&nr_rx_ind_queue); reset_queue(&nr_crc_ind_queue); reset_queue(&nr_uci_ind_queue); + reset_queue(&nr_dl_tti_req_queue); + reset_queue(&nr_tx_req_queue); + reset_queue(&nr_ul_dci_req_queue); + reset_queue(&nr_ul_tti_req_queue); + reset_queue(&nr_wait_ul_tti_req_queue); NR_PRACH_RESOURCES_t prach_resources; memset(&prach_resources, 0, sizeof(prach_resources)); NR_UL_TIME_ALIGNMENT_t ul_time_alignment; memset(&ul_time_alignment, 0, sizeof(ul_time_alignment)); int last_sfn_slot = -1; - uint16_t *sfn_slot_p; - int sfn_slot; + uint16_t sfn_slot = 0; while (!oai_exit) { @@ -255,22 +403,33 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) LOG_E(NR_MAC, "sem_wait() error\n"); abort(); } - sfn_slot_p = get_queue(&nr_sfn_slot_queue); - if (sfn_slot_p == NULL) + uint16_t *slot_ind = get_queue(&nr_sfn_slot_queue); + nr_phy_channel_params_t *ch_info = get_queue(&nr_chan_param_queue); + if (!slot_ind && !ch_info) { - LOG_D(MAC, "get_queue(&nr_sfn_slot_queue) == NULL!\n"); + LOG_D(MAC, "get nr_sfn_slot_queue and nr_chan_param_queue == NULL!\n"); continue; } + if (slot_ind) { + sfn_slot = *slot_ind; + } + else if (ch_info) { + sfn_slot = ch_info->sfn_slot; + } - sfn_slot = *sfn_slot_p; + frame_t frame = NFAPI_SFNSLOT2SFN(sfn_slot); + int slot = NFAPI_SFNSLOT2SLOT(sfn_slot); if (sfn_slot == last_sfn_slot) { LOG_D(NR_MAC, "repeated sfn_sf = %d.%d\n", - sfn_slot >> 6, sfn_slot & 0x3F); + frame, slot); continue; } last_sfn_slot = sfn_slot; + LOG_D(NR_MAC, "The received sfn/slot [%d %d] from proxy\n", + frame, slot); + module_id_t mod_id = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); if (mac->scc == NULL) @@ -282,8 +441,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) mac->ra.generate_nr_prach = 0; int CC_id = 0; uint8_t gNB_id = 0; - frame_t frame = NFAPI_SFNSLOT2SFN(sfn_slot); - int slot = NFAPI_SFNSLOT2SLOT(sfn_slot); nr_uplink_indication_t ul_info; int slots_per_frame = 20; //30 kHZ subcarrier spacing int slot_ahead = 2; // TODO: Make this dynamic @@ -319,71 +476,13 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) { LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind() from %s\n", ul_info.slot_tx, __FUNCTION__); nr_ue_ul_indication(&ul_info); - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info.slot_tx); - if (!ul_config) - { - LOG_E(NR_MAC, "mac->ul_config is null! \n"); - continue; - } - if (mac->ra.ra_state != RA_SUCCEEDED) - { - AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), - "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); - fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; - uint8_t nr_prach = nr_ue_get_rach(&prach_resources, prach_pdu, mod_id, CC_id, ul_info.frame_tx, gNB_id, ul_info.slot_tx); - if (nr_prach == 1) - { - L1_nsa_prach_procedures(ul_info.frame_tx, ul_info.slot_tx, prach_pdu); - ul_config->number_pdus = 0; - ul_info.ue_sched_mode = SCHED_ALL; - } - else if (nr_prach == 2) - { - LOG_I(NR_PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, mod_id); - } - else if(nr_prach == 3) - { - LOG_I(NR_PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, mod_id); - } - } - } - - nfapi_nr_rach_indication_t *rach_ind = unqueue_matching(&nr_rach_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot); - nfapi_nr_rx_data_indication_t *rx_ind = unqueue_matching(&nr_rx_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot); - nfapi_nr_crc_indication_t *crc_ind = unqueue_matching(&nr_crc_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot); - - if (rach_ind && rach_ind->number_of_pdus > 0) - { - NR_UL_IND_t UL_INFO = { - .rach_ind = *rach_ind, - }; - send_nsa_standalone_msg(&UL_INFO, rach_ind->header.message_id); - for (int i = 0; i < rach_ind->number_of_pdus; i++) - { - free(rach_ind->pdu_list[i].preamble_list); - } - free(rach_ind->pdu_list); - free(rach_ind); - nr_Msg1_transmitted(mod_id, CC_id, frame, gNB_id); - } - if (crc_ind && crc_ind->number_crcs > 0) - { - NR_UL_IND_t UL_INFO = { - .crc_ind = *crc_ind, - }; - send_nsa_standalone_msg(&UL_INFO, crc_ind->header.message_id); - free(crc_ind->crc_list); - free(crc_ind); - } - if (rx_ind && rx_ind->number_of_pdus > 0) - { - NR_UL_IND_t UL_INFO = { - .rx_ind = *rx_ind, - }; - send_nsa_standalone_msg(&UL_INFO, rx_ind->header.message_id); - free(rx_ind->pdu_list); - free(rx_ind); + check_nr_prach(mac, &ul_info, &prach_resources); } + process_queued_nr_nfapi_msgs(mac, sfn_slot); + free(slot_ind); + slot_ind = NULL; + free(ch_info); + ch_info = NULL; } return NULL; } diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 45b5434361..b14553a40b 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -783,17 +783,21 @@ int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind) case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_0_1; nfapi_nr_uci_pucch_pdu_format_0_1_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_0_1; - - uci_ind_pdu->harq = CALLOC(1, sizeof(*uci_ind_pdu->harq)); - AssertFatal(uci_ind_pdu->harq != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication."); + if (ind_pdu->sr) { + uci_ind_pdu->sr = CALLOC(1, sizeof(*uci_ind_pdu->sr)); + AssertFatal(uci_ind_pdu->sr != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication."); + *uci_ind_pdu->sr = *ind_pdu->sr; + } + if (ind_pdu->harq) { + uci_ind_pdu->harq = CALLOC(1, sizeof(*uci_ind_pdu->harq)); + AssertFatal(uci_ind_pdu->harq != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication."); - *uci_ind_pdu->harq = *ind_pdu->harq; - - 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 = *ind_pdu->harq; + 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; + } break; } @@ -827,8 +831,16 @@ int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind) { if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE) { - free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list); - free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq); + if (uci_ind->uci_list[i].pucch_pdu_format_0_1.harq) { + free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list); + uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL; + free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq); + uci_ind->uci_list[i].pucch_pdu_format_0_1.harq = NULL; + } + if (uci_ind->uci_list[i].pucch_pdu_format_0_1.sr) { + free(uci_ind->uci_list[i].pucch_pdu_format_0_1.sr); + uci_ind->uci_list[i].pucch_pdu_format_0_1.sr = NULL; + } } if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE) { @@ -838,7 +850,9 @@ int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind) } } free(uci_ind->uci_list); + uci_ind->uci_list = NULL; free(uci_ind); + uci_ind = NULL; } } else { diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index eae45fbba5..15ac90aae2 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -5866,7 +5866,12 @@ static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *valu )) return 0; if (value->pduBitmap & 0x01) { //SR - value->sr = (nfapi_nr_sr_pdu_0_1_t*) malloc(sizeof(nfapi_nr_sr_pdu_0_1_t)); + value->sr = nfapi_p7_allocate(sizeof(*value->sr), config); + if (value->sr == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate sr pdu\n", __FUNCTION__); + return 0; + } if(!(pull8(ppReadPackedMsg, &value->sr->sr_indication, end) && pull8(ppReadPackedMsg, &value->sr->sr_confidence_level, end) )) diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 2111933216..c2ae84963b 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -48,7 +48,6 @@ const char *ul_pdu_type[]={"PRACH", "PUCCH", "PUSCH", "SRS"}; queue_t nr_rx_ind_queue; queue_t nr_crc_ind_queue; queue_t nr_uci_ind_queue; -queue_t nr_sfn_slot_queue; int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response) { @@ -182,38 +181,22 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response 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); - pdu_0_1->pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR + memset(pdu_0_1, 0, sizeof(*pdu_0_1)); pdu_0_1->handle = 0; pdu_0_1->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti; pdu_0_1->pucch_format = 1; - pdu_0_1->ul_cqi = 27; + pdu_0_1->ul_cqi = 255; pdu_0_1->timing_advance = 0; pdu_0_1->rssi = 0; - 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; - } } LOG_I(NR_PHY, "In %s: Filled queue uci_ind which was filled by dlconfig.\n" - "uci_num %d, uci_slot %d, uci_frame %d and num_harqs %d\n", - __FUNCTION__, uci_ind->num_ucis, uci_ind->slot, uci_ind->sfn, uci_ind->uci_list[0].pucch_pdu_format_0_1.harq->num_harq); + "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[0].pucch_pdu_format_0_1.harq->harq_list); - //free(uci_ind->uci_list[0].pucch_pdu_format_0_1.harq); - 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; - free(pdu_0_1->harq->harq_list); - free(pdu_0_1->harq); - } free(uci_ind->uci_list); free(uci_ind); } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 8d60aa74f5..ce1f5fe1af 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -435,6 +435,8 @@ typedef struct { nr_downlink_indication_t dl_info; NR_UE_HARQ_STATUS_t dl_harq_info[16]; bool expected_dci; + bool index_has_dci[16]; + int active_harq_sfn_slot; pthread_mutex_t mutex_dl_info; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 1273a76da8..e178dbd9e0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1282,8 +1282,10 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, // FIXME k0 != 0 currently not taken into consideration current_harq->dl_frame = frame; current_harq->dl_slot = slot; + mac->active_harq_sfn_slot = NFAPI_SFNSLOT2HEX(frame, (slot + data_toul_fb)); - LOG_D(PHY,"Setting harq_status for harq_id %d, dl %d.%d\n",harq_id,frame,slot); + LOG_D(NR_PHY,"Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d\n", + harq_id, frame, slot, frame, (slot + data_toul_fb)); } @@ -2756,7 +2758,7 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, // check BWP id if (mac->DLbwp[0]) N_RB=NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); else N_RB=mac->type0_PDCCH_CSS_config.num_rbs; -; + // indicating a DL DCI format 1bit pos++; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 5df7e3d707..932a49418e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1268,7 +1268,7 @@ int nr_acknack_scheduling(int mod_id, // Find the right timing_indicator value. int i = 0; while (i < 8) { - if (pdsch_to_harq_feedback[i] == pucch->ul_slot - slot) + if (pdsch_to_harq_feedback[i] == (pucch->ul_slot - slot) % n_slots_frame) break; ++i; } @@ -1315,7 +1315,7 @@ int nr_acknack_scheduling(int mod_id, while (i < 8) { LOG_D(NR_MAC,"pdsch_to_harq_feedback[%d] = %d (pucch->ul_slot %d - slot %d)\n", i,pdsch_to_harq_feedback[i],pucch->ul_slot,slot); - if (pdsch_to_harq_feedback[i] == pucch->ul_slot - slot) { + if (pdsch_to_harq_feedback[i] == (pucch->ul_slot - slot) % n_slots_frame) { ind_found = i; break; } diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index aa10ca0116..f5a7e8b0cd 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -152,8 +152,14 @@ void handle_nr_uci(NR_UL_IND_t *UL_info) for (int i = 0; i < num_ucis; i++) { switch (uci_list[i].pdu_type) { case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: - free(uci_list[i].pucch_pdu_format_0_1.harq->harq_list); + if (uci_list[i].pucch_pdu_format_0_1.harq) { + free(uci_list[i].pucch_pdu_format_0_1.harq->harq_list); + uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL; + } free(uci_list[i].pucch_pdu_format_0_1.harq); + uci_list[i].pucch_pdu_format_0_1.harq = NULL; + free(uci_list[i].pucch_pdu_format_0_1.sr); + uci_list[i].pucch_pdu_format_0_1.sr = NULL; break; case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: @@ -163,9 +169,12 @@ void handle_nr_uci(NR_UL_IND_t *UL_info) break; } } - if (uci_ind && num_ucis > 0) + if (uci_ind && num_ucis > 0) { free(uci_list); + uci_list = NULL; + } free(uci_ind); + uci_ind = NULL; } static bool crc_sfn_slot_matcher(void *wanted, void *candidate) diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 2e89229e90..9dc6cf918f 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -52,9 +52,16 @@ static nr_ue_if_module_t *nr_ue_if_module_inst[MAX_IF_MODULES]; static int ue_tx_sock_descriptor = -1; static int ue_rx_sock_descriptor = -1; static int g_harq_pid; -int current_sfn_slot; sem_t sfn_slot_semaphore; +queue_t nr_sfn_slot_queue; +queue_t nr_chan_param_queue; +queue_t nr_dl_tti_req_queue; +queue_t nr_tx_req_queue; +queue_t nr_ul_dci_req_queue; +queue_t nr_ul_tti_req_queue; +queue_t nr_wait_ul_tti_req_queue; + void nrue_init_standalone_socket(int tx_port, int rx_port) { { @@ -87,7 +94,7 @@ void nrue_init_standalone_socket(int tx_port, int rx_port) } assert(ue_tx_sock_descriptor == -1); ue_tx_sock_descriptor = sd; - LOG_D(NR_RRC, "Sucessfully set up tx_socket in %s.\n", __FUNCTION__); + LOG_D(NR_RRC, "Successfully set up tx_socket in %s.\n", __FUNCTION__); } { @@ -113,7 +120,7 @@ void nrue_init_standalone_socket(int tx_port, int rx_port) } assert(ue_rx_sock_descriptor == -1); ue_rx_sock_descriptor = sd; - LOG_D(NR_RRC, "Sucessfully set up rx_socket in %s.\n", __FUNCTION__); + LOG_D(NR_RRC, "Successfully set up rx_socket in %s.\n", __FUNCTION__); } LOG_I(NR_RRC, "NRUE standalone socket info: tx_port %d rx_port %d on %s.\n", tx_port, rx_port, stub_eth_params.remote_addr); @@ -229,6 +236,7 @@ static void copy_dl_tti_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_ { NR_UE_MAC_INST_t *mac = get_mac_inst(dl_info->module_id); mac->expected_dci = false; + memset(mac->index_has_dci, 0, sizeof(*mac->index_has_dci)); int pdu_idx = 0; int num_pdus = dl_tti_request->dl_tti_request_body.nPDUs; @@ -262,7 +270,7 @@ static void copy_dl_tti_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_ for (int j = 0; j < num_dcis; j++) { nfapi_nr_dl_dci_pdu_t *dci_pdu_list = &pdu_list->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[j]; - if ((dci_pdu_list->RNTI != mac->crnti) && + if ((dci_pdu_list->RNTI != mac->crnti) && ((dci_pdu_list->RNTI != mac->ra.ra_rnti) || mac->ra.RA_RAPID_found)) { LOG_D(NR_MAC, "We are filtering PDCCH DCI pdu because RNTI doesnt match!\n"); @@ -271,6 +279,8 @@ static void copy_dl_tti_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_ } fill_dl_info_with_pdcch(dl_info->dci_ind, dci_pdu_list, pdu_idx); mac->expected_dci = true; + LOG_D(NR_MAC, "Setting index_has_dci[%d] = true\n", j); + mac->index_has_dci[j] = true; pdu_idx++; } } @@ -280,6 +290,36 @@ static void copy_dl_tti_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_ dl_info->frame = dl_tti_request->SFN; } +static void fill_rx_ind(nfapi_nr_pdu_t *pdu_list, fapi_nr_rx_indication_t *rx_ind, int pdu_idx, int pdu_type) +{ + AssertFatal(pdu_list->num_TLV < sizeof(pdu_list->TLVs) / sizeof(pdu_list->TLVs[0]), "Num TLVs exceeds TLV array size"); + int length = 0; + for (int j = 0; j < pdu_list->num_TLV; j++) + { + length += pdu_list->TLVs[j].length; + } + LOG_I(NR_PHY, "%s: num_tlv %d and length %d, pdu index %d\n", + __FUNCTION__, pdu_list->num_TLV, length, pdu_idx); + uint8_t *pdu = malloc(length); + AssertFatal(pdu != NULL, "%s: Out of memory in malloc", __FUNCTION__); + rx_ind->rx_indication_body[pdu_idx].pdsch_pdu.pdu = pdu; + for (int j = 0; j < pdu_list->num_TLV; j++) + { + const uint32_t *ptr; + if (pdu_list->TLVs[j].tag) + ptr = pdu_list->TLVs[j].value.ptr; + else + ptr = pdu_list->TLVs[j].value.direct; + memcpy(pdu, ptr, pdu_list->TLVs[j].length); + pdu += pdu_list->TLVs[j].length; + } + rx_ind->rx_indication_body[pdu_idx].pdsch_pdu.ack_nack = 1; + rx_ind->rx_indication_body[pdu_idx].pdsch_pdu.pdu_length = length; + rx_ind->rx_indication_body[pdu_idx].pdu_type = pdu_type; + +} + + static void copy_tx_data_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_nr_tx_data_request_t *tx_data_request) { NR_UE_MAC_INST_t *mac = get_mac_inst(dl_info->module_id); @@ -292,45 +332,34 @@ static void copy_tx_data_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi dl_info->rx_ind = CALLOC(1, sizeof(fapi_nr_rx_indication_t)); AssertFatal(dl_info->rx_ind != NULL, "%s: Out of memory in calloc", __FUNCTION__); - dl_info->rx_ind->sfn = tx_data_request->SFN; - dl_info->rx_ind->slot = tx_data_request->Slot; - dl_info->rx_ind->number_pdus = num_pdus; + fapi_nr_rx_indication_t *rx_ind = dl_info->rx_ind; + rx_ind->sfn = tx_data_request->SFN; + rx_ind->slot = tx_data_request->Slot; + + int pdu_idx = 0; for (int i = 0; i < num_pdus; i++) { nfapi_nr_pdu_t *pdu_list = &tx_data_request->pdu_list[i]; - AssertFatal(pdu_list->num_TLV < sizeof(pdu_list->TLVs) / sizeof(pdu_list->TLVs[0]), "Num TLVs exceeds TLV array size"); - int length = 0; - for (int j = 0; j < pdu_list->num_TLV; j++) + if(mac->ra.ra_state <= WAIT_RAR) { - length += pdu_list->TLVs[j].length; + fill_rx_ind(pdu_list, rx_ind, pdu_idx, FAPI_NR_RX_PDU_TYPE_RAR); + pdu_idx++; } - LOG_I(NR_PHY, "%s: num_tlv %d and length %d, pdu index %d\n", - __FUNCTION__, pdu_list->num_TLV, length, i); - uint8_t *pdu = malloc(length); - AssertFatal(pdu != NULL, "%s: Out of memory in malloc", __FUNCTION__); - dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu = pdu; - for (int j = 0; j < pdu_list->num_TLV; j++) + else if (mac->index_has_dci[i]) { - const uint32_t *ptr; - if (pdu_list->TLVs[j].tag) - ptr = pdu_list->TLVs[j].value.ptr; - else - ptr = pdu_list->TLVs[j].value.direct; - memcpy(pdu, ptr, pdu_list->TLVs[j].length); - pdu += pdu_list->TLVs[j].length; + fill_rx_ind(pdu_list, rx_ind, pdu_idx, FAPI_NR_RX_PDU_TYPE_DLSCH); + pdu_idx++; } - dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.ack_nack = 1; - dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu_length = length; - if (tx_data_request->Slot == 7 && mac->ra.ra_state <= WAIT_RAR) { - dl_info->rx_ind->rx_indication_body[i].pdu_type = FAPI_NR_RX_PDU_TYPE_RAR; - } - else { - dl_info->rx_ind->rx_indication_body[i].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH; + else + { + LOG_D(NR_MAC, "mac->index_has_dci[%d] = 0, so this index contained a DCI for a different UE\n", i); } + } dl_info->slot = tx_data_request->Slot; dl_info->frame = tx_data_request->SFN; + dl_info->rx_ind->number_pdus = pdu_idx; } 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) @@ -392,32 +421,70 @@ static void copy_ul_tti_data_req_to_dl_info(nr_downlink_indication_t *dl_info, n for (int i = 0; i < num_pdus; i++) { nfapi_nr_ul_tti_request_number_of_pdus_t *pdu_list = &ul_tti_req->pdus_list[i]; - LOG_D(NR_PHY, "This is the pdu type %d and rnti %x in ul_tti_req\n", - pdu_list->pdu_type, ul_tti_req->pdus_list[i].pucch_pdu.rnti); + LOG_D(NR_PHY, "This is the pdu type %d and rnti %x and SR flag %d and harq_pdu_len %d in in ul_tti_req\n", + pdu_list->pdu_type, ul_tti_req->pdus_list[i].pucch_pdu.rnti, pdu_list->pucch_pdu.sr_flag, pdu_list->pucch_pdu.bit_len_harq); if (pdu_list->pdu_type == NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE && pdu_list->pucch_pdu.rnti == mac->crnti) { + LOG_I(NR_MAC, "This is the number of UCIs in the queue %ld\n", nr_uci_ind_queue.num_items); nfapi_nr_uci_indication_t *uci_ind = get_queue(&nr_uci_ind_queue); - if (uci_ind) + if (uci_ind && uci_ind->num_ucis > 0) { - if (uci_ind->num_ucis > 0) - { - uci_ind->sfn = ul_tti_req->SFN; - uci_ind->slot = ul_tti_req->Slot; - LOG_I(NR_MAC, "We have dequeued the previously filled uci_ind and updated the snf/slot to %d/%d.\n", - uci_ind->sfn, uci_ind->slot); - NR_UL_IND_t UL_INFO = { - .uci_ind = *uci_ind, - }; - send_nsa_standalone_msg(&UL_INFO, uci_ind->header.message_id); - } + 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; 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; - free(pdu_0_1->harq->harq_list); - free(pdu_0_1->harq); + 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) + { + 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++) + { + pdu_0_1->harq->harq_list[k].harq_value = 0; + } + } + } + LOG_I(NR_MAC, "We have dequeued the previously filled uci_ind and updated the snf/slot to %d/%d.\n", + uci_ind->sfn, uci_ind->slot); + NR_UL_IND_t UL_INFO = { + .uci_ind = *uci_ind, + }; + send_nsa_standalone_msg(&UL_INFO, uci_ind->header.message_id); + + 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; } } @@ -442,7 +509,7 @@ static void fill_dci_from_dl_config(nr_downlink_indication_t*dl_ind, fapi_nr_dl_ int num_dci_options = rel15_dci->num_dci_options; if (num_dci_options <= 0) { - LOG_I(NR_MAC, "num_dci_opts = %d for %dth pdu in dl_config_list\n", rel15_dci->num_dci_options, i); + LOG_I(NR_MAC, "num_dci_opts = %d for pdu[%d] in dl_config_list\n", rel15_dci->num_dci_options, i); } AssertFatal(num_dci_options <= sizeof(rel15_dci->dci_length_options) / sizeof(rel15_dci->dci_length_options[0]), "num_dci_options %d > dci_length_options array\n", num_dci_options); @@ -472,10 +539,10 @@ static void fill_dci_from_dl_config(nr_downlink_indication_t*dl_ind, fapi_nr_dl_ } } -static void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, - nfapi_nr_tx_data_request_t *tx_data_request, - nfapi_nr_ul_dci_request_t *ul_dci_request, - nfapi_nr_ul_tti_request_t *ul_tti_request) +void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, + nfapi_nr_tx_data_request_t *tx_data_request, + nfapi_nr_ul_dci_request_t *ul_dci_request, + nfapi_nr_ul_tti_request_t *ul_tti_request) { frame_t frame = 0; int slot = 0; @@ -500,7 +567,7 @@ static void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, incoming tx_data_request is also destined for the current UE. If the RAR hasn't been processed yet, we do not want to be filtering the tx_data_requests. */ - else if (tx_data_request && (mac->expected_dci || mac->ra.ra_state == WAIT_RAR)) + if (tx_data_request && (mac->expected_dci || mac->ra.ra_state == WAIT_RAR)) { frame = tx_data_request->SFN; slot = tx_data_request->Slot; @@ -524,6 +591,7 @@ static void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, else { if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort(); + LOG_E(NR_MAC, "Error! All indications were NULL\n"); return; } @@ -549,19 +617,9 @@ static void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, { nr_ue_ul_indication(&ul_info); } - - - #if 0 // TODO: Heap use after free caught by sanitizer - free(dl_info.dci_ind); - dl_info.dci_ind = NULL; - - free(dl_info.rx_ind); - dl_info.rx_ind = NULL; - #endif - } -static void save_nr_measurement_info(nfapi_nr_dl_tti_request_t *dl_tti_request) +void save_nr_measurement_info(nfapi_nr_dl_tti_request_t *dl_tti_request) { int num_pdus = dl_tti_request->dl_tti_request_body.nPDUs; char buffer[MAX_MESSAGE_SIZE]; @@ -597,27 +655,127 @@ static void save_nr_measurement_info(nfapi_nr_dl_tti_request_t *dl_tti_request) nsa_sendmsg_to_lte_ue(buffer, pack_len, NR_UE_RRC_MEASUREMENT); LOG_A(NR_RRC, "Populated NR_UE_RRC_MEASUREMENT information and sent to LTE UE\n"); } -uint16_t sfn_slot_pool[512]; -uint16_t sfn_slot_id; + +static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_header_t header) +{ + + switch (header.message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + { + nfapi_nr_dl_tti_request_t *dl_tti_request = MALLOC(sizeof(*dl_tti_request)); + if (nfapi_nr_p7_message_unpack(buffer, len, dl_tti_request, + sizeof(*dl_tti_request), NULL) < 0) + { + LOG_E(NR_PHY, "Message dl_tti_request failed to unpack\n"); + break; + } + LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST message in sfn/slot %d %d. \n", + dl_tti_request->SFN, dl_tti_request->Slot); + if (!put_queue(&nr_dl_tti_req_queue, dl_tti_request)) + { + LOG_E(NR_PHY, "put_queue failed for dl_tti_request.\n"); + free(dl_tti_request); + dl_tti_request = NULL; + } + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: + { + nfapi_nr_tx_data_request_t *tx_data_request = MALLOC(sizeof(*tx_data_request)); + if (nfapi_nr_p7_message_unpack(buffer, len, tx_data_request, + sizeof(*tx_data_request), NULL) < 0) + { + LOG_E(NR_PHY, "Message tx_data_request failed to unpack\n"); + break; + } + LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST message in SFN/slot %d %d. \n", + tx_data_request->SFN, tx_data_request->Slot); + if (!put_queue(&nr_tx_req_queue, tx_data_request)) + { + LOG_E(NR_PHY, "put_queue failed for tx_request.\n"); + free(tx_data_request); + tx_data_request = NULL; + } + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: + { + nfapi_nr_ul_dci_request_t *ul_dci_request = MALLOC(sizeof(*ul_dci_request)); + if (nfapi_nr_p7_message_unpack(buffer, len, ul_dci_request, + sizeof(*ul_dci_request), NULL) < 0) + { + LOG_E(NR_PHY, "Message ul_dci_request failed to unpack\n"); + break; + } + LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST message in SFN/slot %d %d. \n", + ul_dci_request->SFN, ul_dci_request->Slot); + if (!put_queue(&nr_ul_dci_req_queue, ul_dci_request)) + { + LOG_E(NR_PHY, "put_queue failed for ul_dci_request.\n"); + free(ul_dci_request); + ul_dci_request = NULL; + } + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: + { + nfapi_nr_ul_tti_request_t *ul_tti_request = MALLOC(sizeof(*ul_tti_request)); + if (nfapi_nr_p7_message_unpack(buffer, len, ul_tti_request, + sizeof(*ul_tti_request), NULL) < 0) + { + LOG_E(NR_PHY, "Message ul_tti_request failed to unpack\n"); + break; + } + 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. + { + 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); + } + break; + } + + default: + LOG_E(NR_PHY, "Invalid nFAPI message. Header ID %d\n", + header.message_id); + break; + } + return; +} void *nrue_standalone_pnf_task(void *context) { - NR_UE_MAC_INST_t *mac = get_mac_inst(0); struct sockaddr_in server_address; socklen_t addr_len = sizeof(server_address); - char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; - char buffer_for_tx_data_req[NFAPI_MAX_PACKED_MESSAGE_SIZE]; - ssize_t len_of_tx_data_req = 0; - int sfn_of_tx_data_req = 0; - int slot_of_tx_data_req = 0; - int sfn_of_dl_tti_req = 0; - int slot_of_dl_tti_req = 0; - int sfn = 0; - int slot = 0; - int delta = 0; int sd = ue_rx_sock_descriptor; assert(sd > 0); - LOG_I(NR_RRC, "Sucessfully started %s.\n", __FUNCTION__); + + char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; + + LOG_I(NR_RRC, "Successfully started %s.\n", __FUNCTION__); while (true) { @@ -634,160 +792,51 @@ void *nrue_standalone_pnf_task(void *context) } if (len == sizeof(uint16_t)) { - uint16_t sfn_slot = 0; - memcpy((void *)&sfn_slot, buffer, sizeof(sfn_slot)); - current_sfn_slot = sfn_slot; + uint16_t *sfn_slot = CALLOC(1, sizeof(*sfn_slot)); + memcpy(sfn_slot, buffer, sizeof(*sfn_slot)); - sfn_slot_pool[sfn_slot_id] = sfn_slot; + LOG_I(NR_PHY, "Received from proxy sfn %d slot %d\n", + NFAPI_SFNSLOT2SFN(*sfn_slot), NFAPI_SFNSLOT2SLOT(*sfn_slot)); - if (!put_queue(&nr_sfn_slot_queue, &sfn_slot_pool[sfn_slot_id])) + if (!put_queue(&nr_sfn_slot_queue, sfn_slot)) { LOG_E(NR_PHY, "put_queue failed for sfn slot.\n"); } - sfn_slot_id = (sfn_slot_id + 1) % 512; - if (sem_post(&sfn_slot_semaphore) != 0) { LOG_E(NR_PHY, "sem_post() error\n"); abort(); } - sfn = NFAPI_SFNSLOT2SFN(sfn_slot); - slot = NFAPI_SFNSLOT2SLOT(sfn_slot); - LOG_I(NR_PHY, "Received from proxy sfn %d slot %d\n", sfn, slot); } else if (len == sizeof(nr_phy_channel_params_t)) { - nr_phy_channel_params_t ch_info; - memcpy(&ch_info, buffer, sizeof(nr_phy_channel_params_t)); - current_sfn_slot = ch_info.sfn_slot; + nr_phy_channel_params_t *ch_info = CALLOC(1, sizeof(*ch_info)); + memcpy(ch_info, buffer, sizeof(*ch_info)); - sfn_slot_pool[sfn_slot_id] = ch_info.sfn_slot; + LOG_I(NR_PHY, "Received_SINR = %f, sfn:slot %d:%d\n", + ch_info->sinr, NFAPI_SFNSLOT2SFN(ch_info->sfn_slot), NFAPI_SFNSLOT2SLOT(ch_info->sfn_slot)); - if (!put_queue(&nr_sfn_slot_queue, &sfn_slot_pool[sfn_slot_id])) + if (!put_queue(&nr_chan_param_queue, ch_info)) { LOG_E(NR_PHY, "put_queue failed for sfn slot.\n"); } - sfn_slot_id = (sfn_slot_id + 1) % 512; - if (sem_post(&sfn_slot_semaphore) != 0) { LOG_E(MAC, "sem_post() error\n"); abort(); } - sfn = NFAPI_SFNSLOT2SFN(ch_info.sfn_slot); - slot = NFAPI_SFNSLOT2SLOT(ch_info.sfn_slot); - LOG_I(NR_PHY, "Received_SINR = %f, sfn:slot %d:%d\n", ch_info.sinr, sfn, slot); } else { nfapi_p7_message_header_t header; - nfapi_nr_dl_tti_request_t dl_tti_request; - nfapi_nr_ul_tti_request_t ul_tti_request; - nfapi_nr_tx_data_request_t tx_data_request; - nfapi_nr_ul_dci_request_t ul_dci_request; - if (nfapi_p7_message_header_unpack((void *)buffer, len, &header, sizeof(header), NULL) < 0) + if (nfapi_p7_message_header_unpack(buffer, len, &header, sizeof(header), NULL) < 0) { LOG_E(NR_PHY, "Header unpack failed for nrue_standalone pnf\n"); continue; } - else - { - switch (header.message_id) - { - case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: - if (nfapi_nr_p7_message_unpack((void *)buffer, len, &dl_tti_request, - sizeof(nfapi_nr_dl_tti_request_t), NULL) < 0) - { - LOG_E(NR_PHY, "Message dl_tti_request failed to unpack\n"); - break; - } - LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST message in sfn/slot %d %d. \n", - dl_tti_request.SFN, dl_tti_request.Slot); - save_nr_measurement_info(&dl_tti_request); - check_and_process_dci(&dl_tti_request, NULL, NULL, NULL); - if (mac->expected_dci) - { - sfn_of_dl_tti_req = dl_tti_request.SFN; - slot_of_dl_tti_req = dl_tti_request.Slot; - } - if (len_of_tx_data_req > 0 - && sfn_of_dl_tti_req == sfn_of_tx_data_req - && slot_of_dl_tti_req == slot_of_tx_data_req) - { - if (nfapi_nr_p7_message_unpack((void *)buffer_for_tx_data_req, len_of_tx_data_req, &tx_data_request, - sizeof(tx_data_request), NULL) < 0) - { - LOG_E(NR_PHY, "Message tx_data_request failed to unpack\n"); - break; - } - LOG_I(NR_PHY, "Processing an NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST message in SFN/slot %d %d. \n", - tx_data_request.SFN, tx_data_request.Slot); - check_and_process_dci(NULL, &tx_data_request, NULL, NULL); - len_of_tx_data_req = 0; - } - break; - case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: - if (nfapi_nr_p7_message_unpack((void *)buffer, len, &tx_data_request, - sizeof(tx_data_request), NULL) < 0) - { - LOG_E(NR_PHY, "Message tx_data_request failed to unpack\n"); - break; - } - LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST message in SFN/slot %d %d. \n", - tx_data_request.SFN, tx_data_request.Slot); - - if (tx_data_request.SFN == sfn_of_dl_tti_req && tx_data_request.Slot == slot_of_dl_tti_req - && (mac->expected_dci || mac->ra.ra_state <= WAIT_RAR)) - { - check_and_process_dci(NULL, &tx_data_request, NULL, NULL); - } - else - { - len_of_tx_data_req = len; - sfn_of_tx_data_req = tx_data_request.SFN; - slot_of_tx_data_req = tx_data_request.Slot; - memcpy(buffer_for_tx_data_req, buffer, len); - LOG_I(NR_PHY, "Saved an NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST message in SFN/slot %d %d. \n", - tx_data_request.SFN, tx_data_request.Slot); - } - break; - case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: - if (nfapi_nr_p7_message_unpack((void *)buffer, len, &ul_dci_request, - sizeof(ul_dci_request), NULL) < 0) - { - LOG_E(NR_PHY, "Message ul_dci_request failed to unpack\n"); - break; - } - LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST message in SFN/slot %d %d. \n", - ul_dci_request.SFN, ul_dci_request.Slot); - delta = NFAPI_SFNSLOT2DEC(sfn, slot) - NFAPI_SFNSLOT2DEC(ul_dci_request.SFN, ul_dci_request.Slot); - if (delta < -NFAPI_SFNSLOT2DEC(512, 0)) - { - delta += NFAPI_SFNSLOT2DEC(1024, 0); - } - if (delta < 6) - { - check_and_process_dci(NULL, NULL, &ul_dci_request, NULL); - } - break; - case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: - if (nfapi_nr_p7_message_unpack((void *)buffer, len, &ul_tti_request, - sizeof(ul_tti_request), NULL) < 0) - { - LOG_E(NR_PHY, "Message ul_tti_request failed to unpack\n"); - break; - } - 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); - check_and_process_dci(NULL, NULL, NULL, &ul_tti_request); - break; - default: - LOG_E(NR_PHY, "Case Statement has no corresponding nfapi message, this is the header ID %d\n", header.message_id); - break; - } - } + enqueue_nr_nfapi_msg(buffer, len, header); } } //while(true) } @@ -905,7 +954,6 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci_index->dci_format]; g_harq_pid = def_dci_pdu_rel15->harq_pid; LOG_D(NR_MAC, "Setting harq_pid = %d and dci_index = %d (based on format)\n", g_harq_pid, dci_index->dci_format); - memset(def_dci_pdu_rel15, 0, sizeof(*def_dci_pdu_rel15)); ret_mask |= (ret << FAPI_NR_DCI_IND); if (ret >= 0) { @@ -914,7 +962,10 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot, dl_info->thread_id); nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response); } + memset(def_dci_pdu_rel15, 0, sizeof(*def_dci_pdu_rel15)); } + free(dl_info->dci_ind); + dl_info->dci_ind = NULL; } if (dl_info->rx_ind != NULL) { @@ -955,6 +1006,8 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ break; } } + free(dl_info->rx_ind); + dl_info->rx_ind = NULL; } //clean up nr_downlink_indication_t *dl_info diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 055da7e3a6..37771282c0 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -223,7 +223,6 @@ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id); void nrue_init_standalone_socket(int tx_port, int rx_port); void *nrue_standalone_pnf_task(void *context); -extern int current_sfn_slot; extern sem_t sfn_slot_semaphore; typedef struct nfapi_dl_tti_config_req_tx_data_req_t @@ -234,6 +233,13 @@ typedef struct nfapi_dl_tti_config_req_tx_data_req_t void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id); +void save_nr_measurement_info(nfapi_nr_dl_tti_request_t *dl_tti_request); + +void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, + nfapi_nr_tx_data_request_t *tx_data_request, + nfapi_nr_ul_dci_request_t *ul_dci_request, + nfapi_nr_ul_tti_request_t *ul_tti_request); + /**\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); diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 9876f4a4a7..1598e3d620 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -37,6 +37,7 @@ #include "openair1/PHY/defs_gNB.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" #include "openair1/PHY/LTE_TRANSPORT/transport_common.h" +#include "softmodem-common.h" extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void configure_nfapi_pnf(char *vnf_ip_addr, @@ -2060,8 +2061,12 @@ static float get_bler_val(uint8_t mcs, int sinr) static inline bool is_channel_modeling(void) { /* TODO: For now we enable channel modeling based on the node_number. - Replace with a command line option to enable/disable channel modeling. */ - return node_number == 0; + Replace with a command line option to enable/disable channel modeling. + The LTE UE will crash when channel modeling is conducted for NSA + mode. It does not crash for LTE mode. We have not implemented channel + modeling for NSA mode yet. For now, we ensure only do do chanel modeling + in LTE mode. */ + return node_number == 0 && !get_softmodem_params()->nsa; } static bool should_drop_transport_block(int sf, uint16_t rnti) diff --git a/openair2/PHY_INTERFACE/queue.c b/openair2/PHY_INTERFACE/queue.c index c6e1fb6d2f..d837857ac7 100644 --- a/openair2/PHY_INTERFACE/queue.c +++ b/openair2/PHY_INTERFACE/queue.c @@ -25,6 +25,34 @@ void reset_queue(queue_t *q) } } +void *put_queue_replace(queue_t *q, void *item) +{ + assert(item != NULL); + if (pthread_mutex_lock(&q->mutex) != 0) + { + LOG_ERROR("put_queue: mutex_lock failed"); + return false; + } + + void *evicted = NULL; + if (q->num_items >= MAX_QUEUE_SIZE) + { + evicted = q->items[q->read_index]; + assert(evicted != NULL); + q->items[q->read_index] = NULL; + q->read_index = (q->read_index + 1) % MAX_QUEUE_SIZE; + q->num_items--; + } + assert(q->items[q->write_index] == NULL); + q->items[q->write_index] = item; + q->write_index = (q->write_index + 1) % MAX_QUEUE_SIZE; + q->num_items++; + + pthread_mutex_unlock(&q->mutex); + return evicted; +} + + bool put_queue(queue_t *q, void *item) { assert(item != NULL); diff --git a/openair2/PHY_INTERFACE/queue.h b/openair2/PHY_INTERFACE/queue.h index d274f7b0cd..4678e31030 100644 --- a/openair2/PHY_INTERFACE/queue.h +++ b/openair2/PHY_INTERFACE/queue.h @@ -42,6 +42,7 @@ typedef struct queue_t void init_queue(queue_t *q); void reset_queue(queue_t *q); +void *put_queue_replace(queue_t *q, void *item); bool put_queue(queue_t *q, void *item); void *get_queue(queue_t *q); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index d3a2868d4d..6a45794e16 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -2774,6 +2774,12 @@ static void start_oai_nrue_threads() init_queue(&nr_crc_ind_queue); init_queue(&nr_uci_ind_queue); init_queue(&nr_sfn_slot_queue); + init_queue(&nr_chan_param_queue); + init_queue(&nr_dl_tti_req_queue); + init_queue(&nr_tx_req_queue); + init_queue(&nr_ul_dci_req_queue); + init_queue(&nr_ul_tti_req_queue); + init_queue(&nr_wait_ul_tti_req_queue); if (sem_init(&sfn_slot_semaphore, 0, 0) != 0) { diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index d152f574b0..3c074b04ef 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -46,6 +46,12 @@ extern queue_t nr_rx_ind_queue; extern queue_t nr_crc_ind_queue; extern queue_t nr_uci_ind_queue; extern queue_t nr_sfn_slot_queue; +extern queue_t nr_chan_param_queue; +extern queue_t nr_dl_tti_req_queue; +extern queue_t nr_tx_req_queue; +extern queue_t nr_ul_dci_req_queue; +extern queue_t nr_ul_tti_req_queue; +extern queue_t nr_wait_ul_tti_req_queue; // // main_rrc.c //