From 4dfe7c259642364f21368c8bd4067e86ae5a18d6 Mon Sep 17 00:00:00 2001 From: Melissa Elkadi Date: Thu, 1 Jul 2021 12:21:57 -0700 Subject: [PATCH] 5G Userplane working 50% of the time This commit includes several changes. First, it updates the way we fill the uplink UCI indication. This still has some todo comments since all the fields in this ind were hardcoded. It also updates the pack and unpack functions for the NR_UCI incations. Lastly, it includes updates to the gNB UCI scheduler. The updates in the gNB were cherry picked from develop. There are two updates to the VNF which allow the VNF timing/slots to be adjusted based on the received timing_info packets from the VNF. This adjustment was disabled in IISc's nFAPI code. For now, it is improving the timing between the VNF and PNF. --- nfapi/open-nFAPI/nfapi/src/nfapi_p7.c | 129 +++++++++++------- nfapi/open-nFAPI/vnf/src/vnf_interface.c | 2 +- nfapi/open-nFAPI/vnf/src/vnf_p7.c | 7 +- nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c | 2 +- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 65 +++++---- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 123 ++++++++++------- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 4 +- 7 files changed, 203 insertions(+), 129 deletions(-) diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index 900306bc48..6ee9dec122 100755 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -3533,28 +3533,27 @@ static uint8_t pack_nr_uci_pucch_0_1(void* tlv, uint8_t **ppWritePackedMsg, uint push16(value->rnti, ppWritePackedMsg, end) && push8(value->pucch_format, ppWritePackedMsg, end) && push8(value->ul_cqi, ppWritePackedMsg, end) && - push16(value->timing_advance, ppWritePackedMsg, end) && + push16(value->timing_advance, ppWritePackedMsg, end) && push16(value->rssi, ppWritePackedMsg, end) )) return 0; if (value->pduBitmap & 0x01) { //SR - if(!(push8(value->sr->sr_indication, ppWritePackedMsg, end) && - push8(value->sr->sr_confidence_level, ppWritePackedMsg, end) + if (!(push8(value->sr->sr_indication, ppWritePackedMsg, end) && + push8(value->sr->sr_confidence_level, ppWritePackedMsg, end) )) return 0; } if (((value->pduBitmap >> 1) & 0x01)) { //HARQ - if(!(push8(value->harq->num_harq, ppWritePackedMsg, end) && - push8(value->harq->harq_confidence_level, ppWritePackedMsg, end) + if (!(push8(value->harq->num_harq, ppWritePackedMsg, end) && + push8(value->harq->harq_confidence_level, ppWritePackedMsg, end) )) return 0; - - for(int i=0; iharq->num_harq;i++) + for (int i = 0; i < value->harq->num_harq; i++) { - if(!(push8(value->harq->harq_list[i].harq_value, ppWritePackedMsg, end) + if (!(push8(value->harq->harq_list[i].harq_value, ppWritePackedMsg, end) )) - return 0; + return 0; } } @@ -3618,20 +3617,22 @@ static uint8_t pack_nr_uci_indication_body(void* tlv, uint8_t **ppWritePackedMsg return 0; switch (value->pdu_type) { - case NFAPI_NR_UCI_PUSCH_PDU_TYPE: - NFAPI_TRACE(NFAPI_TRACE_WARN, "Unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE \n"); - break; + case NFAPI_NR_UCI_PUSCH_PDU_TYPE: + NFAPI_TRACE(NFAPI_TRACE_WARN, "Unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE \n"); + break; - case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { - nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &value->pucch_pdu_format_0_1; - pack_nr_uci_pucch_0_1(uci_pdu, ppWritePackedMsg, end); - break; - } - 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; - pack_nr_uci_pucch_2_3_4(uci_pdu, ppWritePackedMsg, end); - break; - } + case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { + nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &value->pucch_pdu_format_0_1; + if (!pack_nr_uci_pucch_0_1(uci_pdu, ppWritePackedMsg, end)) + return 0; + break; + } + 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 (!pack_nr_uci_pucch_2_3_4(uci_pdu, ppWritePackedMsg, end)) + return 0; + break; + } } return 1; @@ -3647,10 +3648,10 @@ static uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uin )) return 0; - for(int i=0; inum_ucis;i++) + for (int i = 0; i < pNfapiMsg->num_ucis; i++) { - if(!pack_nr_uci_indication_body(&(pNfapiMsg->uci_list[i]),ppWritePackedMsg,end)) - return 0; + if (!pack_nr_uci_indication_body(&(pNfapiMsg->uci_list[i]), ppWritePackedMsg, end)) + return 0; } return 1; @@ -6529,7 +6530,7 @@ static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *valu uint8_t *end, nfapi_p7_codec_config_t *config) { - if(!(pull8(ppReadPackedMsg, &value->pduBitmap, end) && + if (!(pull8(ppReadPackedMsg, &value->pduBitmap, end) && pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end) && pull8(ppReadPackedMsg, &value->pucch_format, end) && @@ -6539,21 +6540,37 @@ 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 - if(!(pull8(ppReadPackedMsg, &value->sr->sr_indication, end) && - pull8(ppReadPackedMsg, &value->sr->sr_confidence_level, end) + if (!(pull8(ppReadPackedMsg, &value->sr->sr_indication, end) && + pull8(ppReadPackedMsg, &value->sr->sr_confidence_level, end) )) return 0; } if (((value->pduBitmap >> 1) & 0x01)) { //HARQ + value->harq = nfapi_p7_allocate(sizeof(*value->harq), config); - if (!(pull8(ppReadPackedMsg, &value->harq->harq_confidence_level, end) && - pull8(ppReadPackedMsg, &value->harq->num_harq, end) + if (value->harq == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate nr_harq pdu\n", __FUNCTION__); + return 0; + } + if (!(pull8(ppReadPackedMsg, &value->harq->num_harq, end) && + pull8(ppReadPackedMsg, &value->harq->harq_confidence_level, end) )) return 0; - value->harq->harq_list = nfapi_p7_allocate(sizeof(*value->harq->harq_list) * value->harq->num_harq, config); - for (int i = 0; i < value->harq->num_harq; i++) { - if (!pull8(ppReadPackedMsg, &value->harq->harq_list[i].harq_value, end)) + value->harq->harq_list = NULL; + if (value->harq->num_harq > 0) { + value->harq->harq_list = nfapi_p7_allocate(sizeof(*value->harq->harq_list) * value->harq->num_harq, config); + if (value->harq->harq_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", + __FUNCTION__, value->harq->num_harq); return 0; + } + for (int i = 0; i < value->harq->num_harq; i++) { + if (!pull8(ppReadPackedMsg, &value->harq->harq_list[i].harq_value, end)) { + return 0; + } + } } } @@ -6607,33 +6624,39 @@ static uint8_t unpack_nr_uci_pucch_2_3_4(void* tlv, uint8_t **ppReadPackedMsg, u return 1; } -static uint8_t unpack_nr_uci_indication_body(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t *value, + uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_p7_codec_config_t *config) { - nfapi_nr_uci_t* value = (nfapi_nr_uci_t*)tlv; - if(!(pull16(ppReadPackedMsg, &value->pdu_type, end) && pull16(ppReadPackedMsg, &value->pdu_size, end) )) return 0; - + switch (value->pdu_type) { - case NFAPI_NR_UCI_PUSCH_PDU_TYPE: - NFAPI_TRACE(NFAPI_TRACE_WARN, "Unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE \n"); - break; + case NFAPI_NR_UCI_PUSCH_PDU_TYPE: + NFAPI_TRACE(NFAPI_TRACE_WARN, "Unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE \n"); + break; - case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { - nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu = &value->pucch_pdu_format_0_1; - unpack_nr_uci_pucch_0_1(&uci_pdu, ppReadPackedMsg, end); - break; + case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { + nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &value->pucch_pdu_format_0_1; + if (!unpack_nr_uci_pucch_0_1(uci_pdu, ppReadPackedMsg, end, config)) + return 0; + break; + } + 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)) + return 0; + break; + } + default: + NFAPI_TRACE(NFAPI_TRACE_WARN, "Unexpected pdu type %d\n", value->pdu_type); + break; } - 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; - unpack_nr_uci_pucch_2_3_4(&uci_pdu, ppReadPackedMsg, end); - break; - } - } - return 1; + return 1; } static uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) @@ -6646,11 +6669,11 @@ static uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, )) return 0; - pNfapiMsg->uci_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->uci_list) * pNfapiMsg->num_ucis, config); + pNfapiMsg->uci_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->uci_list) * pNfapiMsg->num_ucis, config); for (int i = 0; i < pNfapiMsg->num_ucis; i++) { if(!unpack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppReadPackedMsg, end, config)) - return 0; + return 0; } return 1; diff --git a/nfapi/open-nFAPI/vnf/src/vnf_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_interface.c index 01d3423692..a1ef78679e 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_interface.c @@ -1154,7 +1154,7 @@ int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy info->timing_window = 30; // This seems to override what gets set by the user - why??? //TODO: Change in NR in terms of microsecends,what should be the value? info->timing_info_mode = 0x03; - info->timing_info_period = 128; + info->timing_info_period = 12; // Melissa come back to this nfapi_vnf_phy_info_list_add(config, info); diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c index cdcd4f25eb..3c7f0d1056 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -2022,9 +2022,12 @@ void vnf_nr_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) // Panos: Careful here!!! Modification of the original nfapi-code //if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1) //printf("VNF-PNF delta - %d", vnf_pnf_sfnslot_delta); - if (vnf_pnf_sfnslot_delta>0 || vnf_pnf_sfnslot_delta < 0) + if (vnf_pnf_sfnslot_delta != 0) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF delta:%d VNF:%d PNF:%d\n\n\n\n\n\n\n\n\n", __FUNCTION__, vnf_pnf_sfnslot_delta,NFAPI_SFNSLOT2DEC(vnf_p7->p7_connections[0].sfn,vnf_p7->p7_connections[0].slot),NFAPI_SFNSLOT2DEC(ind.last_sfn,ind.last_slot)) ; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF. Delta %d. PNF:%d.%d VNF:%d.%d\n\n\n\n\n\n\n\n\n", + __FUNCTION__, vnf_pnf_sfnslot_delta, + ind.last_sfn, ind.last_slot, + vnf_p7->p7_connections[0].sfn, vnf_p7->p7_connections[0].slot); // Panos: Careful here!!! Modification of the original nfapi-code vnf_p7->p7_connections[0].sfn = ind.last_sfn; vnf_p7->p7_connections[0].slot = ind.last_slot; diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c index 3777e02153..3f9073799c 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c @@ -170,7 +170,7 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config) struct timespec slot_start; // clock_gettime(CLOCK_MONOTONIC, &sf_start); clock_gettime(CLOCK_MONOTONIC, &slot_start); - long millisecond = slot_start.tv_nsec / 1e6; //Check if we have to change + long millisecond = slot_start.tv_nsec / 0.5e6; //Check if we have to change //long millisecond = slot_start.tv_nsec / 0.5e6; // sf_start = timespec_add(sf_start, sf_duration); slot_start = timespec_add(slot_start, slot_duration); diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 73989688a1..46083faf56 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -155,33 +155,50 @@ 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 == 19 ? scheduled_response->frame + 1 % 1024 : scheduled_response->frame; - uci_ind->slot = (scheduled_response->slot + 6) % 20; + uci_ind->sfn = scheduled_response->frame; + uci_ind->slot = scheduled_response->slot + 6; // (+ 6) Specified by pucch->ul_slot field in gNB uci scheduler + if (uci_ind->slot >= 20) + { + uci_ind->slot %= 20; + uci_ind->sfn = (uci_ind->sfn + 1) % 1024; + } uci_ind->num_ucis = 1; - uci_ind->uci_list = CALLOC(1, sizeof(nfapi_nr_uci_t)); - uci_ind->uci_list[0].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE; - uci_ind->uci_list[0].pdu_size = 46; - uci_ind->uci_list->pucch_pdu_format_0_1.rnti = scheduled_response->dl_config->dl_config_list[0].dlsch_config_pdu.rnti; - uci_ind->uci_list[0].pucch_pdu_format_0_1.pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR - uci_ind->uci_list[0].pucch_pdu_format_0_1.pucch_format = 1; - uci_ind->uci_list[0].pucch_pdu_format_0_1.harq = CALLOC(1, sizeof(nfapi_nr_harq_pdu_0_1_t)); - uci_ind->uci_list[0].pucch_pdu_format_0_1.harq->harq_confidence_level = 0; - uci_ind->uci_list[0].pucch_pdu_format_0_1.harq->num_harq = 1; - uci_ind->uci_list[0].pucch_pdu_format_0_1.harq->harq_list = CALLOC(1, sizeof(nfapi_nr_harq_t)); - uci_ind->uci_list->pucch_pdu_format_0_1.harq->harq_list[0].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\n", - __FUNCTION__, uci_ind->num_ucis, uci_ind->slot, uci_ind->sfn); - - if (!put_queue(&nr_uci_ind_queue, uci_ind)) + uci_ind->uci_list = CALLOC(uci_ind->num_ucis, sizeof(*uci_ind->uci_list)); + 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; + uci_ind->uci_list[j].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE; + uci_ind->uci_list[j].pdu_size = 46; //Melissa hack TODO: What should this be? Format 1_1 DCI has PayloadBitSize = 46 + pdu_0_1->pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR + pdu_0_1->handle = 0; + pdu_0_1->rnti = dl_config->dl_config_list[0].dlsch_config_pdu.rnti; + pdu_0_1->pucch_format = 1; + pdu_0_1->ul_cqi = 27; + 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++) { - LOG_E(NR_MAC, "Put_queue failed for rx_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); - free(uci_ind->uci_list); - free(uci_ind); + pdu_0_1->harq->harq_list[k].harq_value = 0; } - break; //Melissa figure out what to send to gNB when receiving format 1_1 + } + + 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); + + 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); + free(uci_ind->uci_list); + free(uci_ind); + } + break; } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 360ef7c565..298c6c4222 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -315,60 +315,78 @@ static void handle_dl_harq(module_id_t mod_id, } } +static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t slot, int UE_id) +{ + /* In case of realtime problems: we can only identify a HARQ process by + * timing. If the HARQ process's feedback_frame/feedback_slot is not the one we + * expected, we assume that processing has been aborted and we need to + * skip this HARQ process, which is what happens in the loop below. + * Similarly, we might be "in advance", in which case we need to skip + * this result. */ + NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id]; + int8_t pid = sched_ctrl->feedback_dl_harq.head; + if (pid < 0) + return NULL; + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid]; + /* old feedbacks we missed: mark for retransmission */ + while (harq->feedback_slot < slot) { + LOG_W(MAC, + "expected HARQ pid %d feedback at slot %d, but is at %d.%d instead (HARQ feedback is in the past)\n", + pid, + harq->feedback_slot, + frame, + slot); + remove_front_nr_list(&sched_ctrl->feedback_dl_harq); + handle_dl_harq(mod_id, UE_id, pid, 0); + pid = sched_ctrl->feedback_dl_harq.head; + if (pid < 0) + return NULL; + harq = &sched_ctrl->harq_processes[pid]; + } + /* feedbacks that we wait for in the future: don't do anything */ + if (harq->feedback_slot > slot) { + LOG_W(MAC, + "expected HARQ pid %d feedback at slot %d, but is at %d.%d instead (HARQ feedback is in the future)\n", + pid, + harq->feedback_slot, + frame, + slot); + return NULL; + } + return harq; +} + void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, sub_frame_t slot, const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01) -{ NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; - UE_info->active[0] = 1; - UE_info->rnti[0] = uci_01->rnti; +{ int UE_id = find_nr_UE_id(mod_id, uci_01->rnti); if (UE_id < 0) { LOG_E(MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_01->rnti); return; } - //NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; + NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - // tpc (power control) - sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, - uci_01->ul_cqi, - 30); - - // NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; - // const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; - //const int num_slots = 20; - - // if (((uci_01->pduBitmap >> 1) & 0x01)) { - // // iterate over received harq bits - // for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) { - // const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value; - // const uint8_t harq_confidence = uci_01->harq->harq_confidence_level; - // const int feedback_slot = (slot - 1 + num_slots) % num_slots; - // /* In case of realtime problems: we can only identify a HARQ process by - // * timing. If the HARQ process's feedback_slot is not the one we - // * expected, we assume that processing has been aborted and we need to - // * skip this HARQ process, which is what happens in the loop below. If - // * you don't experience real-time problems, you might simply revert the - // * commit that introduced these changes. */ - // int8_t pid = sched_ctrl->feedback_dl_harq.head; - // DevAssert(pid >= 0); - // while (sched_ctrl->harq_processes[pid].feedback_slot != feedback_slot) { - // LOG_W(MAC, - // "expected feedback slot %d, but found %d instead\n", - // sched_ctrl->harq_processes[pid].feedback_slot, - // feedback_slot); - // remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - // handle_dl_harq(mod_id, UE_id, pid, 0); - // pid = sched_ctrl->feedback_dl_harq.head; - // DevAssert(pid >= 0); - // } - // remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - // NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid]; - // DevAssert(harq->is_waiting); - // handle_dl_harq(mod_id, UE_id, pid, harq_value == 1 && harq_confidence == 0); - // } - // } + if (((uci_01->pduBitmap >> 1) & 0x01)) { + // iterate over received harq bits + for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) { + const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value; + const uint8_t harq_confidence = uci_01->harq->harq_confidence_level; + NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id); + if (!harq) { + LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__); + break; + } + DevAssert(harq->is_waiting); + const int8_t pid = sched_ctrl->feedback_dl_harq.head; + remove_front_nr_list(&sched_ctrl->feedback_dl_harq); + /* Melissa: according to nfapi_nr_interface_scf.h, harq_value = 0 is a pass + (check below was for harq_value == 1 in develop branch) */ + handle_dl_harq(mod_id, UE_id, pid, harq_value == 0 && harq_confidence == 0); + } + } } void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, @@ -497,8 +515,8 @@ int nr_acknack_scheduling(int mod_id, || (pucch->frame == frame + 1)) return -1; - // this is hardcoded for now as ue specific - NR_SearchSpace__searchSpaceType_PR ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + // this is hardcoded for now as ue specific only if we are not on the initialBWP (to be fixed to allow ue_Specific also on initialBWP + NR_SearchSpace__searchSpaceType_PR ss_type = sched_ctrl->active_bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific: NR_SearchSpace__searchSpaceType_PR_common; uint8_t pdsch_to_harq_feedback[8]; get_pdsch_to_harq_feedback(mod_id, UE_id, ss_type, pdsch_to_harq_feedback); @@ -601,13 +619,26 @@ int nr_acknack_scheduling(int mod_id, pucch->timing_indicator = i; // index in the list of timing indicators + LOG_I(NR_MAC,"2. DL slot %d, UL_ACK %d (index %d)\n", slot, pucch->ul_slot, i); + pucch->dai_c++; pucch->resource_indicator = 0; // each UE has dedicated PUCCH resources + NR_PUCCH_Config_t *pucch_Config = NULL; + if (sched_ctrl->active_ubwp) { + pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; + } else if (RC.nrmac[mod_id]->UE_info.secondaryCellGroup[UE_id] && + RC.nrmac[mod_id]->UE_info.secondaryCellGroup[UE_id]->spCellConfig && + RC.nrmac[mod_id]->UE_info.secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated && + RC.nrmac[mod_id]->UE_info.secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig && + RC.nrmac[mod_id]->UE_info.secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && + RC.nrmac[mod_id]->UE_info.secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { + pucch_Config = RC.nrmac[mod_id]->UE_info.secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; + } + /* verify that at that slot and symbol, resources are free. We only do this * for initialCyclicShift 0 (we assume it always has that one), so other * initialCyclicShifts can overlap with ICS 0!*/ - const NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[pucch->resource_indicator]; DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0); if (resource->format.choice.format0->initialCyclicShift == 0) { diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 78355d714a..e1e0c37970 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -83,8 +83,8 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) void handle_nr_uci(NR_UL_IND_t *UL_info) { const module_id_t mod_id = UL_INFO.module_id; - const frame_t frame = UL_INFO.frame; - const sub_frame_t slot = UL_INFO.slot; + const frame_t frame = UL_INFO.uci_ind.sfn; + const sub_frame_t slot = UL_INFO.uci_ind.slot; int num_ucis = UL_INFO.uci_ind.num_ucis; nfapi_nr_uci_t *uci_list = UL_INFO.uci_ind.uci_list;