Commit 9da3cbc9 authored by Melissa Elkadi's avatar Melissa Elkadi

Cherry picking UCI multiplexing for CSI reports

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