Commit 4dfe7c25 authored by Melissa Elkadi's avatar Melissa Elkadi

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.
parent 90d56417
......@@ -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; i<value->harq->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_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_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;
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; i<pNfapiMsg->num_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;
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
}
}
}
......
......@@ -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) {
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment