diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h index 276f417fbb..1094e82fa7 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h @@ -69,4 +69,5 @@ #define FAPI_NR_UL_CONFIG_TYPE_SRS 0x04 #define FAPI_NR_UL_CONFIG_TYPES 0x04 +#define FAPI_NR_END 0xff #endif diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 8e1ea55fec..296789e167 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -391,20 +391,22 @@ typedef struct { } fapi_nr_ul_config_srs_pdu; typedef struct { - uint8_t pdu_type; + int pdu_type; union { fapi_nr_ul_config_prach_pdu prach_config_pdu; fapi_nr_ul_config_pucch_pdu pucch_config_pdu; nfapi_nr_ue_pusch_pdu_t pusch_config_pdu; fapi_nr_ul_config_srs_pdu srs_config_pdu; }; + pthread_mutex_t* lock; + int* privateNBpdus; } fapi_nr_ul_config_request_pdu_t; typedef struct { int frame; int slot; int number_pdus; - fapi_nr_ul_config_request_pdu_t ul_config_list[FAPI_NR_UL_CONFIG_LIST_NUM]; + fapi_nr_ul_config_request_pdu_t ul_config_list[FAPI_NR_UL_CONFIG_LIST_NUM + 1]; // +1 to have space for iterator ending pthread_mutex_t mutex_ul_config; } fapi_nr_ul_config_request_t; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 5257a72ea6..476ec8db67 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -104,192 +104,182 @@ 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) { - int frame = scheduled_response->ul_config->frame; - int slot = scheduled_response->ul_config->slot; - fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config; - AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), - "Too many ul_config pdus %d", ul_config->number_pdus); - for (int i = 0; i < ul_config->number_pdus; ++i) { - LOG_D(NR_PHY, "In %s: processing type %d PDU of %d total UL PDUs (ul_config %p) \n", - __FUNCTION__, ul_config->ul_config_list[i].pdu_type, ul_config->number_pdus, ul_config); + if (scheduled_response && scheduled_response->ul_config) { + int frame = scheduled_response->ul_config->frame; + int slot = scheduled_response->ul_config->slot; + fapi_nr_ul_config_request_pdu_t *it = fapiLockIterator(scheduled_response->ul_config, frame, slot); + while (it->pdu_type != FAPI_NR_END) { + switch (it->pdu_type) { + case FAPI_NR_UL_CONFIG_TYPE_PRACH: { + fapi_nr_ul_config_prach_pdu *prach_pdu = &it->prach_config_pdu; + nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind)); + rach_ind->sfn = frame; + rach_ind->slot = slot; + rach_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION; + uint8_t pdu_index = 0; + rach_ind->pdu_list = CALLOC(1, sizeof(*rach_ind->pdu_list)); + rach_ind->number_of_pdus = 1; + rach_ind->pdu_list[pdu_index].phy_cell_id = prach_pdu->phys_cell_id; + rach_ind->pdu_list[pdu_index].symbol_index = prach_pdu->prach_start_symbol; + rach_ind->pdu_list[pdu_index].slot_index = prach_pdu->prach_slot; + rach_ind->pdu_list[pdu_index].freq_index = prach_pdu->num_ra; + rach_ind->pdu_list[pdu_index].avg_rssi = 128; + rach_ind->pdu_list[pdu_index].avg_snr = 0xff; // invalid for now + rach_ind->pdu_list[pdu_index].num_preamble = 1; + const int num_p = rach_ind->pdu_list[pdu_index].num_preamble; + rach_ind->pdu_list[pdu_index].preamble_list = calloc(num_p, sizeof(nfapi_nr_prach_indication_preamble_t)); + rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_index = prach_pdu->ra_PreambleIndex; + rach_ind->pdu_list[pdu_index].preamble_list[0].timing_advance = 0; + rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff; - uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type; - switch (pdu_type) { - case FAPI_NR_UL_CONFIG_TYPE_PRACH: { - fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[i].prach_config_pdu; - nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind)); - rach_ind->sfn = frame; - rach_ind->slot = slot; - rach_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION; - uint8_t pdu_index = 0; - rach_ind->pdu_list = CALLOC(1, sizeof(*rach_ind->pdu_list)); - rach_ind->number_of_pdus = 1; - rach_ind->pdu_list[pdu_index].phy_cell_id = prach_pdu->phys_cell_id; - rach_ind->pdu_list[pdu_index].symbol_index = prach_pdu->prach_start_symbol; - rach_ind->pdu_list[pdu_index].slot_index = prach_pdu->prach_slot; - rach_ind->pdu_list[pdu_index].freq_index = prach_pdu->num_ra; - rach_ind->pdu_list[pdu_index].avg_rssi = 128; - rach_ind->pdu_list[pdu_index].avg_snr = 0xff; // invalid for now - rach_ind->pdu_list[pdu_index].num_preamble = 1; - const int num_p = rach_ind->pdu_list[pdu_index].num_preamble; - rach_ind->pdu_list[pdu_index].preamble_list = calloc(num_p, sizeof(nfapi_nr_prach_indication_preamble_t)); - rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_index = prach_pdu->ra_PreambleIndex; - rach_ind->pdu_list[pdu_index].preamble_list[0].timing_advance = 0; - rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff; - - if (!put_queue(&nr_rach_ind_queue, rach_ind)) { - for (int pdu_index = 0; pdu_index < rach_ind->number_of_pdus; pdu_index++) - free(rach_ind->pdu_list[pdu_index].preamble_list); - free(rach_ind->pdu_list); - free(rach_ind); - } - LOG_D(NR_MAC, "We have successfully filled the rach_ind queue with the recently filled rach ind\n"); - break; + if (!put_queue(&nr_rach_ind_queue, rach_ind)) { + for (int pdu_index = 0; pdu_index < rach_ind->number_of_pdus; pdu_index++) + free(rach_ind->pdu_list[pdu_index].preamble_list); + free(rach_ind->pdu_list); + free(rach_ind); } - case (FAPI_NR_UL_CONFIG_TYPE_PUSCH): { - nfapi_nr_rx_data_indication_t *rx_ind = CALLOC(1, sizeof(*rx_ind)); - nfapi_nr_crc_indication_t *crc_ind = CALLOC(1, sizeof(*crc_ind)); - nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu; - if (pusch_config_pdu->tx_request_body.pdu) { - rx_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION; - rx_ind->sfn = frame; - rx_ind->slot = slot; - rx_ind->number_of_pdus = 1; // scheduled_response->tx_request->number_of_pdus; - rx_ind->pdu_list = CALLOC(rx_ind->number_of_pdus, sizeof(*rx_ind->pdu_list)); - for (int j = 0; j < rx_ind->number_of_pdus; j++) { - fapi_nr_tx_request_body_t *tx_req_body = &pusch_config_pdu->tx_request_body; - rx_ind->pdu_list[j].handle = pusch_config_pdu->handle; - rx_ind->pdu_list[j].harq_id = pusch_config_pdu->pusch_data.harq_process_id; - rx_ind->pdu_list[j].pdu_length = tx_req_body->pdu_length; - rx_ind->pdu_list[j].pdu = CALLOC(tx_req_body->pdu_length, sizeof(*rx_ind->pdu_list[j].pdu)); - memcpy(rx_ind->pdu_list[j].pdu, tx_req_body->pdu, tx_req_body->pdu_length * sizeof(*rx_ind->pdu_list[j].pdu)); - rx_ind->pdu_list[j].rnti = pusch_config_pdu->rnti; - /* TODO: Implement channel modeling to abstract TA and CQI. For now, - we hard code the values below since they are set in L1 and we are - abstracting L1. */ - rx_ind->pdu_list[j].timing_advance = 31; - rx_ind->pdu_list[j].ul_cqi = 255; - } - - crc_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION; - crc_ind->number_crcs = scheduled_response->ul_config->number_pdus; - crc_ind->sfn = frame; - crc_ind->slot = slot; - crc_ind->crc_list = CALLOC(crc_ind->number_crcs, sizeof(*crc_ind->crc_list)); - for (int j = 0; j < crc_ind->number_crcs; j++) { - crc_ind->crc_list[j].handle = pusch_config_pdu->handle; - crc_ind->crc_list[j].harq_id = pusch_config_pdu->pusch_data.harq_process_id; - LOG_D(NR_MAC, "This is the harq pid %d for crc_list[%d]\n", crc_ind->crc_list[j].harq_id, j); - LOG_D(NR_MAC, "This is sched sfn/sl [%d %d] and crc sfn/sl [%d %d]\n", frame, slot, crc_ind->sfn, crc_ind->slot); - crc_ind->crc_list[j].num_cb = pusch_config_pdu->pusch_data.num_cb; - crc_ind->crc_list[j].rnti = pusch_config_pdu->rnti; - crc_ind->crc_list[j].tb_crc_status = 0; - crc_ind->crc_list[j].timing_advance = 31; - crc_ind->crc_list[j].ul_cqi = 255; - AssertFatal(mac->nr_ue_emul_l1.harq[crc_ind->crc_list[j].harq_id].active_ul_harq_sfn_slot == -1, - "We did not send an active CRC when we should have!\n"); - mac->nr_ue_emul_l1.harq[crc_ind->crc_list[j].harq_id].active_ul_harq_sfn_slot = - NFAPI_SFNSLOT2HEX(crc_ind->sfn, crc_ind->slot); - LOG_D(NR_MAC, - "This is sched sfn/sl [%d %d] and crc sfn/sl [%d %d] with mcs_index in ul_cqi -> %d\n", - frame, - slot, - crc_ind->sfn, - crc_ind->slot, - pusch_config_pdu->mcs_index); - } - - if (!put_queue(&nr_rx_ind_queue, rx_ind)) { - LOG_E(NR_MAC, "Put_queue failed for rx_ind\n"); - for (int i = 0; i < rx_ind->number_of_pdus; i++) { - free(rx_ind->pdu_list[i].pdu); - rx_ind->pdu_list[i].pdu = NULL; - } - - free(rx_ind->pdu_list); - rx_ind->pdu_list = NULL; - free(rx_ind); - rx_ind = NULL; - } - if (!put_queue(&nr_crc_ind_queue, crc_ind)) { - LOG_E(NR_MAC, "Put_queue failed for crc_ind\n"); - free(crc_ind->crc_list); - crc_ind->crc_list = NULL; - free(crc_ind); - crc_ind = NULL; - } - - LOG_D(PHY, "In %s: Filled queue rx/crc_ind which was filled by ulconfig. \n", __FUNCTION__); - } - 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 = frame; - uci_ind->slot = 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++) { - LOG_D(NR_MAC, "ul_config->ul_config_list[%d].pucch_config_pdu.n_bit = %d\n", i, ul_config->ul_config_list[i].pucch_config_pdu.n_bit); - if (ul_config->ul_config_list[i].pucch_config_pdu.n_bit > 3 && mac->nr_ue_emul_l1.num_csi_reports > 0) { - 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); - 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; - fill_uci_2_3_4(pdu_2_3_4, &ul_config->ul_config_list[i].pucch_config_pdu); - } - 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; - if (mac->nr_ue_emul_l1.num_harqs > 0) { - int harq_index = 0; - pdu_0_1->pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR - pdu_0_1->harq.num_harq = mac->nr_ue_emul_l1.num_harqs; - pdu_0_1->harq.harq_confidence_level = 0; - int harq_pid = -1; - for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) { - if (mac->nr_ue_emul_l1.harq[k].active && - mac->nr_ue_emul_l1.harq[k].active_dl_harq_sfn == uci_ind->sfn && - mac->nr_ue_emul_l1.harq[k].active_dl_harq_slot == uci_ind->slot) { - mac->nr_ue_emul_l1.harq[k].active = false; - harq_pid = k; - AssertFatal(harq_index < pdu_0_1->harq.num_harq, "Invalid harq_index %d\n", harq_index); - pdu_0_1->harq.harq_list[harq_index].harq_value = !mac->dl_harq_info[k].ack; - harq_index++; - } - } - AssertFatal(harq_pid != -1, "No active harq_pid, sfn_slot = %u.%u", uci_ind->sfn, uci_ind->slot); - } - } - } - - LOG_D(NR_PHY, "Sending UCI with %d PDUs in sfn.slot %d/%d\n", - uci_ind->num_ucis, 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); - free_uci_inds(uci_ind); - break; - } - - default: - LOG_W(NR_MAC, "Unknown ul_config->pdu_type %d\n", pdu_type); + LOG_D(NR_MAC, "We have successfully filled the rach_ind queue with the recently filled rach ind\n"); break; } + case (FAPI_NR_UL_CONFIG_TYPE_PUSCH): { + nfapi_nr_rx_data_indication_t *rx_ind = CALLOC(1, sizeof(*rx_ind)); + nfapi_nr_crc_indication_t *crc_ind = CALLOC(1, sizeof(*crc_ind)); + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &it->pusch_config_pdu; + if (pusch_config_pdu->tx_request_body.pdu) { + rx_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION; + rx_ind->sfn = frame; + rx_ind->slot = slot; + rx_ind->number_of_pdus = 1; + rx_ind->pdu_list = CALLOC(rx_ind->number_of_pdus, sizeof(*rx_ind->pdu_list)); + for (int j = 0; j < rx_ind->number_of_pdus; j++) { + fapi_nr_tx_request_body_t *tx_req_body = &pusch_config_pdu->tx_request_body; + rx_ind->pdu_list[j].handle = pusch_config_pdu->handle; + rx_ind->pdu_list[j].harq_id = pusch_config_pdu->pusch_data.harq_process_id; + rx_ind->pdu_list[j].pdu_length = tx_req_body->pdu_length; + rx_ind->pdu_list[j].pdu = CALLOC(tx_req_body->pdu_length, sizeof(*rx_ind->pdu_list[j].pdu)); + memcpy(rx_ind->pdu_list[j].pdu, tx_req_body->pdu, tx_req_body->pdu_length * sizeof(*rx_ind->pdu_list[j].pdu)); + rx_ind->pdu_list[j].rnti = pusch_config_pdu->rnti; + /* TODO: Implement channel modeling to abstract TA and CQI. For now, + we hard code the values below since they are set in L1 and we are + abstracting L1. */ + rx_ind->pdu_list[j].timing_advance = 31; + rx_ind->pdu_list[j].ul_cqi = 255; + } + + crc_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION; + crc_ind->number_crcs = rx_ind->number_of_pdus; + crc_ind->sfn = frame; + crc_ind->slot = slot; + crc_ind->crc_list = CALLOC(crc_ind->number_crcs, sizeof(*crc_ind->crc_list)); + for (int j = 0; j < crc_ind->number_crcs; j++) { + crc_ind->crc_list[j].handle = pusch_config_pdu->handle; + crc_ind->crc_list[j].harq_id = pusch_config_pdu->pusch_data.harq_process_id; + LOG_D(NR_MAC, "This is the harq pid %d for crc_list[%d]\n", crc_ind->crc_list[j].harq_id, j); + LOG_D(NR_MAC, "This is sched sfn/sl [%d %d] and crc sfn/sl [%d %d]\n", frame, slot, crc_ind->sfn, crc_ind->slot); + crc_ind->crc_list[j].num_cb = pusch_config_pdu->pusch_data.num_cb; + crc_ind->crc_list[j].rnti = pusch_config_pdu->rnti; + crc_ind->crc_list[j].tb_crc_status = 0; + crc_ind->crc_list[j].timing_advance = 31; + crc_ind->crc_list[j].ul_cqi = 255; + AssertFatal(mac->nr_ue_emul_l1.harq[crc_ind->crc_list[j].harq_id].active_ul_harq_sfn_slot == -1, + "We did not send an active CRC when we should have!\n"); + mac->nr_ue_emul_l1.harq[crc_ind->crc_list[j].harq_id].active_ul_harq_sfn_slot = + NFAPI_SFNSLOT2HEX(crc_ind->sfn, crc_ind->slot); + LOG_D(NR_MAC, + "This is sched sfn/sl [%d %d] and crc sfn/sl [%d %d] with mcs_index in ul_cqi -> %d\n", + frame, + slot, + crc_ind->sfn, + crc_ind->slot, + pusch_config_pdu->mcs_index); + } + + if (!put_queue(&nr_rx_ind_queue, rx_ind)) { + LOG_E(NR_MAC, "Put_queue failed for rx_ind\n"); + for (int i = 0; i < rx_ind->number_of_pdus; i++) { + free(rx_ind->pdu_list[i].pdu); + rx_ind->pdu_list[i].pdu = NULL; + } + + free(rx_ind->pdu_list); + rx_ind->pdu_list = NULL; + free(rx_ind); + rx_ind = NULL; + } + if (!put_queue(&nr_crc_ind_queue, crc_ind)) { + LOG_E(NR_MAC, "Put_queue failed for crc_ind\n"); + free(crc_ind->crc_list); + crc_ind->crc_list = NULL; + free(crc_ind); + crc_ind = NULL; + } + + LOG_D(PHY, "In %s: Filled queue rx/crc_ind which was filled by ulconfig. \n", __FUNCTION__); + } + 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 = frame; + uci_ind->slot = 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++) { + LOG_D(NR_MAC, "pucch_config_pdu.n_bit = %d\n", it->pucch_config_pdu.n_bit); + if (it->pucch_config_pdu.n_bit > 3 && mac->nr_ue_emul_l1.num_csi_reports > 0) { + 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); + 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; + fill_uci_2_3_4(pdu_2_3_4, &it->pucch_config_pdu); + } 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 = it->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; + if (mac->nr_ue_emul_l1.num_harqs > 0) { + int harq_index = 0; + pdu_0_1->pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR + pdu_0_1->harq.num_harq = mac->nr_ue_emul_l1.num_harqs; + pdu_0_1->harq.harq_confidence_level = 0; + int harq_pid = -1; + for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) { + if (mac->nr_ue_emul_l1.harq[k].active && mac->nr_ue_emul_l1.harq[k].active_dl_harq_sfn == uci_ind->sfn + && mac->nr_ue_emul_l1.harq[k].active_dl_harq_slot == uci_ind->slot) { + mac->nr_ue_emul_l1.harq[k].active = false; + harq_pid = k; + AssertFatal(harq_index < pdu_0_1->harq.num_harq, "Invalid harq_index %d\n", harq_index); + pdu_0_1->harq.harq_list[harq_index].harq_value = !mac->dl_harq_info[k].ack; + harq_index++; + } + } + AssertFatal(harq_pid != -1, "No active harq_pid, sfn_slot = %u.%u", uci_ind->sfn, uci_ind->slot); + } + } + } + + LOG_D(NR_PHY, "Sending UCI with %d PDUs in sfn.slot %d/%d\n", uci_ind->num_ucis, 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); + free_uci_inds(uci_ind); + break; + } + + default: + LOG_W(NR_MAC, "Unknown ul_config->pdu_type %d\n", it->pdu_type); + break; } - scheduled_response->ul_config->number_pdus = 0; + it++; } + release_ul_config(it, true); } return 0; } @@ -440,114 +430,52 @@ static void nr_ue_scheduled_response_dl(NR_UE_MAC_INST_t *mac, dl_config->number_pdus = 0; } -static void nr_ue_scheduled_response_ul(PHY_VARS_NR_UE *phy, - fapi_nr_ul_config_request_t *ul_config, - nr_phy_data_tx_t *phy_data, - int module_id, - int cc_id) +static void nr_ue_scheduled_response_ul(PHY_VARS_NR_UE *phy, fapi_nr_ul_config_request_t *ul_config, nr_phy_data_tx_t *phy_data) { - int slot = ul_config->slot; - int pdu_done = 0; - pthread_mutex_lock(&ul_config->mutex_ul_config); + fapi_nr_ul_config_request_pdu_t *pdu = fapiLockIterator(ul_config, ul_config->frame, ul_config->slot); + if (!pdu) { + LOG_E(NR_MAC, "Error in locking ul scheduler dtata\n"); + return; + } - LOG_D(PHY, - "%d.%d ul S ul_config %p pdu_done %d number_pdus %d\n", - ul_config->frame, - slot, - ul_config, - pdu_done, - ul_config->number_pdus); - for (int i = 0; i < ul_config->number_pdus; ++i) { - AssertFatal(ul_config->ul_config_list[i].pdu_type <= FAPI_NR_UL_CONFIG_TYPES, - "pdu_type %d out of bounds\n", - ul_config->ul_config_list[i].pdu_type); - LOG_D(PHY, - "[%d.%d] i %d: processing %s PDU of %d total UL PDUs (ul_config %p) \n", - ul_config->frame, - slot, - i, - ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], - ul_config->number_pdus, - ul_config); - - uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, current_harq_pid, gNB_id = 0; - /* PRACH */ - fapi_nr_ul_config_prach_pdu *prach_config_pdu; - /* PUSCH */ - nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu; - /* PUCCH */ - fapi_nr_ul_config_pucch_pdu *pucch_config_pdu; - LOG_D(PHY, - "%d.%d ul B ul_config %p t %d pdu_done %d number_pdus %d\n", - ul_config->frame, - slot, - ul_config, - pdu_type, - pdu_done, - ul_config->number_pdus); - /* SRS */ - fapi_nr_ul_config_srs_pdu *srs_config_pdu; - - switch (pdu_type) { + while (pdu->pdu_type != FAPI_NR_END) { + switch (pdu->pdu_type) { case FAPI_NR_UL_CONFIG_TYPE_PUSCH: { // pusch config pdu - pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu; - current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id; - NR_UL_UE_HARQ_t *harq_process_ul_ue = &PHY_vars_UE_g[module_id][cc_id]->ul_harq_processes[current_harq_pid]; - NR_UE_ULSCH_t *ulsch = &phy_data->ulsch; - nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch->pusch_pdu; - + int current_harq_pid = pdu->pusch_config_pdu.pusch_data.harq_process_id; + NR_UL_UE_HARQ_t *harq_process_ul_ue = &phy->ul_harq_processes[current_harq_pid]; + nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &phy_data->ulsch.pusch_pdu; LOG_D(PHY, - "In %s i %d: copy pusch_config_pdu nrOfLayers:%d, num_dmrs_cdm_grps_no_data:%d \n", - __FUNCTION__, - i, - pusch_config_pdu->nrOfLayers, - pusch_config_pdu->num_dmrs_cdm_grps_no_data); + "copy pusch_config_pdu nrOfLayers:%d, num_dmrs_cdm_grps_no_data:%d \n", + pdu->pusch_config_pdu.nrOfLayers, + pdu->pusch_config_pdu.num_dmrs_cdm_grps_no_data); - memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t)); - if (pusch_config_pdu->tx_request_body.pdu) { + memcpy(pusch_pdu, &pdu->pusch_config_pdu, sizeof(*pusch_pdu)); + if (pdu->pusch_config_pdu.tx_request_body.pdu) { LOG_D(PHY, "%d.%d Copying %d bytes to harq_process_ul_ue->a (harq_pid %d)\n", ul_config->frame, - slot, - pusch_config_pdu->tx_request_body.pdu_length, + ul_config->slot, + pdu->pusch_config_pdu.tx_request_body.pdu_length, current_harq_pid); - memcpy(harq_process_ul_ue->a, pusch_config_pdu->tx_request_body.pdu, pusch_config_pdu->tx_request_body.pdu_length); + memcpy(harq_process_ul_ue->a, + pdu->pusch_config_pdu.tx_request_body.pdu, + pdu->pusch_config_pdu.tx_request_body.pdu_length); } harq_process_ul_ue->status = ACTIVE; - ul_config->ul_config_list[i].pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more - pdu_done++; - LOG_D(PHY, - "%d.%d ul A ul_config %p t %d pdu_done %d number_pdus %d\n", - ul_config->frame, - slot, - ul_config, - pdu_type, - pdu_done, - ul_config->number_pdus); + pdu->pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more } break; case FAPI_NR_UL_CONFIG_TYPE_PUCCH: { - NR_UE_PUCCH *pucch_vars = &phy_data->pucch_vars; - int found = false; - pucch_config_pdu = &ul_config->ul_config_list[i].pucch_config_pdu; + bool found = false; for (int j = 0; j < 2; j++) { - if (pucch_vars->active[j] == false) { - LOG_D(PHY, "%d.%d Copying pucch pdu to UE PHY\n", ul_config->frame, slot); - memcpy((void *)&(pucch_vars->pucch_pdu[j]), (void *)pucch_config_pdu, sizeof(fapi_nr_ul_config_pucch_pdu)); - pucch_vars->active[j] = true; + if (phy_data->pucch_vars.active[j] == false) { + LOG_D(PHY, "Copying pucch pdu to UE PHY\n"); + phy_data->pucch_vars.pucch_pdu[j] = pdu->pucch_config_pdu; + phy_data->pucch_vars.active[j] = true; found = true; - ul_config->ul_config_list[i].pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more - pdu_done++; - LOG_D(PHY, - "%d.%d ul A ul_config %p t %d pdu_done %d number_pdus %d\n", - ul_config->frame, - slot, - ul_config, - pdu_type, - pdu_done, - ul_config->number_pdus); + pdu->pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more break; } } @@ -555,72 +483,31 @@ static void nr_ue_scheduled_response_ul(PHY_VARS_NR_UE *phy, LOG_E(PHY, "Couldn't find allocation for PUCCH PDU in PUCCH VARS\n"); } break; - case FAPI_NR_UL_CONFIG_TYPE_PRACH: - // prach config pdu - prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu; - memcpy((void *)&(PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_pdu), - (void *)prach_config_pdu, - sizeof(fapi_nr_ul_config_prach_pdu)); - PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->active = true; - ul_config->ul_config_list[i].pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more - pdu_done++; - LOG_D(PHY, - "%d.%d ul A ul_config %p t %d pdu_done %d number_pdus %d\n", - ul_config->frame, - slot, - ul_config, - pdu_type, - pdu_done, - ul_config->number_pdus); - break; + case FAPI_NR_UL_CONFIG_TYPE_PRACH: { + phy->prach_vars[0]->prach_pdu = pdu->prach_config_pdu; + phy->prach_vars[0]->active = true; + pdu->pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more + } break; case FAPI_NR_UL_CONFIG_TYPE_DONE: - pdu_done++; // count the no of pdu processed - LOG_D(PHY, - "%d.%d ul A ul_config %p t %d pdu_done %d number_pdus %d\n", - ul_config->frame, - slot, - ul_config, - pdu_type, - pdu_done, - ul_config->number_pdus); break; case FAPI_NR_UL_CONFIG_TYPE_SRS: // srs config pdu - srs_config_pdu = &ul_config->ul_config_list[i].srs_config_pdu; - memcpy((void *)&(PHY_vars_UE_g[module_id][cc_id]->srs_vars[gNB_id]->srs_config_pdu), - (void *)srs_config_pdu, - sizeof(fapi_nr_ul_config_srs_pdu)); - PHY_vars_UE_g[module_id][cc_id]->srs_vars[gNB_id]->active = true; - ul_config->ul_config_list[i].pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more - pdu_done++; + phy->srs_vars[0]->srs_config_pdu = pdu->srs_config_pdu; + phy->srs_vars[0]->active = true; + pdu->pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more break; default: - ul_config->ul_config_list[i].pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more - pdu_done++; // count the no of pdu processed - LOG_D(PHY, - "%d.%d ul A ul_config %p t %d pdu_done %d number_pdus %d\n", - ul_config->frame, - slot, - ul_config, - pdu_type, - pdu_done, - ul_config->number_pdus); + LOG_W(PHY, "unhandled ul pdu type %d \n", pdu->pdu_type); break; } + pdu++; } - // Clear the fields when all the config pdu are done - if (pdu_done == ul_config->number_pdus) { - ul_config->frame = 0; - ul_config->slot = 0; - ul_config->number_pdus = 0; - LOG_D(PHY, "%d.%d clear ul_config %p\n", ul_config->frame, slot, ul_config); - memset(ul_config->ul_config_list, 0, sizeof(ul_config->ul_config_list)); - } - pthread_mutex_unlock(&ul_config->mutex_ul_config); + LOG_D(PHY, "clear ul_config\n"); + release_ul_config(pdu, true); } int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) @@ -635,11 +522,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) scheduled_response->dl_config, (nr_phy_data_t *)scheduled_response->phy_data); if (scheduled_response->ul_config) - nr_ue_scheduled_response_ul(phy, - scheduled_response->ul_config, - (nr_phy_data_tx_t *)scheduled_response->phy_data, - scheduled_response->module_id, - scheduled_response->CC_id); + nr_ue_scheduled_response_ul(phy, scheduled_response->ul_config, (nr_phy_data_tx_t *)scheduled_response->phy_data); return 0; } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 6240508c55..9700dc5f54 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -483,10 +483,13 @@ void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac); void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs); -fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot, int fb_time); fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot); -void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type); +fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, uint8_t pdu_type); +void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu); +fapi_nr_ul_config_request_pdu_t *fapiLockIterator(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx); + +void release_ul_config(fapi_nr_ul_config_request_pdu_t *pdu, bool clearIt); int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 7105d2f661..722530d696 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -949,19 +949,12 @@ void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack) NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[pid]; int sched_slot = current_harq->ul_slot; int sched_frame = current_harq->ul_frame; - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, sched_slot, 0); - pthread_mutex_lock(&ul_config->mutex_ul_config); mac->nr_ue_emul_l1.num_harqs = 1; - AssertFatal(ul_config->number_pdus < FAPI_NR_UL_CONFIG_LIST_NUM, - "ul_config->number_pdus %d out of bounds\n", - ul_config->number_pdus); - fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu; - PUCCH_sched_t pucch = {0}; - pucch.n_CCE = current_harq->n_CCE; - pucch.N_CCE = current_harq->N_CCE; - pucch.delta_pucch = current_harq->delta_pucch; - pucch.ack_payload = ack_nack; - pucch.n_harq = 1; + PUCCH_sched_t pucch = {.n_CCE = current_harq->n_CCE, + .N_CCE = current_harq->N_CCE, + .delta_pucch = current_harq->delta_pucch, + .ack_payload = ack_nack, + .n_harq = 1}; current_harq->active = false; current_harq->ack_received = false; if (get_softmodem_params()->emulate_l1) { @@ -969,11 +962,11 @@ void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack) mac->nr_ue_emul_l1.harq[pid].active_dl_harq_sfn = sched_frame; mac->nr_ue_emul_l1.harq[pid].active_dl_harq_slot = sched_slot; } - nr_ue_configure_pucch(mac, - sched_slot, - mac->ra.t_crnti, - &pucch, - pucch_pdu); - fill_ul_config(ul_config, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH); - pthread_mutex_unlock(&ul_config->mutex_ul_config); + fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH); + if (!pdu) + return; + int ret = nr_ue_configure_pucch(mac, sched_slot, mac->ra.t_crnti, &pucch, &pdu->pucch_config_pdu); + if (ret != 0) + remove_ul_config_last_item(pdu); + release_ul_config(pdu, false); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index bbc85753bb..0d34585549 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -408,25 +408,15 @@ static int nr_ue_process_dci_ul_00(module_id_t module_id, return -1; } - // Get UL config request corresponding slot_tx - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx, tda_info.k2); - - if (!ul_config) { - LOG_W(MAC, "ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", frame, slot); + fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + if (!pdu) return -1; - } - pthread_mutex_lock(&ul_config->mutex_ul_config); - AssertFatal(ul_config->number_pdus < FAPI_NR_UL_CONFIG_LIST_NUM, - "ul_config->number_pdus %d out of bounds\n", - ul_config->number_pdus); - nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; - - fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); - pthread_mutex_unlock(&ul_config->mutex_ul_config); - - // Config PUSCH PDU - return nr_config_pusch_pdu(mac, &tda_info, pusch_config_pdu, dci, NULL, dci_ind->rnti, NR_UL_DCI_FORMAT_0_0); + int ret = nr_config_pusch_pdu(mac, &tda_info, &pdu->pusch_config_pdu, dci, NULL, dci_ind->rnti, NR_UL_DCI_FORMAT_0_0); + if (ret != 0) + remove_ul_config_last_item(pdu); + release_ul_config(pdu, false); + return ret; } static int nr_ue_process_dci_ul_01(module_id_t module_id, @@ -493,26 +483,14 @@ static int nr_ue_process_dci_ul_01(module_id_t module_id, return -1; } - // Get UL config request corresponding slot_tx - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx, tda_info.k2); - - if (!ul_config) { - LOG_W(MAC, "ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", frame, slot); + fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + if (!pdu) return -1; - } - ul_config->number_pdus = 0; - - pthread_mutex_lock(&ul_config->mutex_ul_config); - AssertFatal(ul_config->number_pdus < FAPI_NR_UL_CONFIG_LIST_NUM, - "ul_config->number_pdus %d out of bounds\n", - ul_config->number_pdus); - nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; - - fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); - pthread_mutex_unlock(&ul_config->mutex_ul_config); - - // Config PUSCH PDU - return nr_config_pusch_pdu(mac, &tda_info, pusch_config_pdu, dci, NULL, dci_ind->rnti, NR_UL_DCI_FORMAT_0_1); + int ret = nr_config_pusch_pdu(mac, &tda_info, &pdu->pusch_config_pdu, dci, NULL, dci_ind->rnti, NR_UL_DCI_FORMAT_0_1); + if (ret != 0) + remove_ul_config_last_item(pdu); + release_ul_config(pdu, false); + return ret; } static int nr_ue_process_dci_dl_10(module_id_t module_id, @@ -4156,32 +4134,21 @@ static void nr_ue_process_rar(nr_downlink_indication_t *dl_info, int pdu_id) ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, tda_info.k2); if (ret != -1) { - - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx, tda_info.k2); uint16_t rnti = mac->crnti; - - if (!ul_config) { - LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); - } - 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); - // Upon successful reception, set the T-CRNTI to the RAR value if the RA preamble is selected among the contention-based RA Preambles if (!ra->cfra) { ra->t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); rnti = ra->t_crnti; send_msg3_rrc_request(mod_id, rnti); } - - pthread_mutex_lock(&ul_config->mutex_ul_config); - AssertFatal(ul_config->number_pdusnumber_pdus %d out of bounds\n",ul_config->number_pdus); - nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; - - fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); - pthread_mutex_unlock(&ul_config->mutex_ul_config); - + fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + if (!pdu) + return; // Config Msg3 PDU - nr_config_pusch_pdu(mac, &tda_info, pusch_config_pdu, NULL, &rar_grant, rnti, NR_DCI_NONE); + int ret = nr_config_pusch_pdu(mac, &tda_info, &pdu->pusch_config_pdu, NULL, &rar_grant, rnti, NR_DCI_NONE); + if (ret != 0) + remove_ul_config_last_item(pdu); + release_ul_config(pdu, false); } } else { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index bba9556add..52bc463d18 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -59,57 +59,84 @@ static void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); -void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type) +fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, uint8_t pdu_type) { - 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); - // clear ul_config for new frame/slot - if ((ul_config->slot != slot_tx || ul_config->frame != frame_tx) && ul_config->number_pdus != 0 - && !get_softmodem_params()->emulate_l1) { - LOG_D(MAC, - "%d.%d %d.%d f clear ul_config %p t %d pdu %d\n", - frame_tx, - slot_tx, - ul_config->frame, - ul_config->slot, - ul_config, - pdu_type, - ul_config->number_pdus); - ul_config->number_pdus = 0; - memset(ul_config->ul_config_list, 0, sizeof(ul_config->ul_config_list)); - } - ul_config->ul_config_list[ul_config->number_pdus].pdu_type = pdu_type; - //ul_config->slot = slot_tx; - //ul_config->sfn = frame_tx; - ul_config->slot = slot_tx; - ul_config->frame = frame_tx; - ul_config->number_pdus++; - - LOG_D(NR_MAC, - "In %s: Set config request for UL transmission in [%d.%d], number of UL PDUs: %d\n", - __FUNCTION__, - ul_config->frame, - ul_config->slot, - ul_config->number_pdus); -} - -/* - * This function returns the UL config corresponding to a given UL slot - * from MAC instance . - */ -fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot, int fb_time) -{ - NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon; - //Check if requested on the right slot - AssertFatal(is_nr_UL_slot(tdd_config, slot, mac->frame_type) != 0, "UL config_request called at wrong slot %d\n", slot); + // Check if requested on the right slot + AssertFatal(is_nr_UL_slot(tdd_config, slot_tx, mac->frame_type) != 0, "UL config_request called at wrong slot %d\n", slot_tx); - int mu = mac->current_UL_BWP ? mac->current_UL_BWP->scs : get_softmodem_params()->numerology; - const int n = nr_slots_per_frame[mu]; - AssertFatal(fb_time < n, "Cannot schedule to a slot more than 1 frame away, ul_config_request is not big enough\n"); AssertFatal(mac->ul_config_request != NULL, "mac->ul_config_request not initialized, logic bug\n"); - return &mac->ul_config_request[slot]; + fapi_nr_ul_config_request_t *ul_config = mac->ul_config_request + slot_tx; + + pthread_mutex_lock(&ul_config->mutex_ul_config); + if (ul_config->number_pdus != 0 && (ul_config->frame != frame_tx || ul_config->slot != slot_tx)) { + LOG_E(NR_MAC, "Error in ul config consistency, clearing slot %d\n", slot_tx); + ul_config->number_pdus = 0; + } + ul_config->frame = frame_tx; + ul_config->slot = slot_tx; + if (ul_config->number_pdus >= FAPI_NR_UL_CONFIG_LIST_NUM) { + LOG_E(NR_MAC, "Error in ul config for slot %d, no memory\n", slot_tx); + pthread_mutex_unlock(&ul_config->mutex_ul_config); + return NULL; + } + fapi_nr_ul_config_request_pdu_t *pdu = ul_config->ul_config_list + ul_config->number_pdus++; + pdu->pdu_type = pdu_type; + AssertFatal(!pdu->lock, "no lock in fapi_nr_ul_config_request_pdu_t, aborting"); + pdu->lock = &ul_config->mutex_ul_config; + pdu->privateNBpdus = &ul_config->number_pdus; + LOG_D(NR_MAC, "Added ul pdu for %d.%d, type %d\n", frame_tx, slot_tx, pdu_type); + return pdu; +} + +void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu) +{ + pdu->privateNBpdus--; +} + +void release_ul_config(fapi_nr_ul_config_request_pdu_t *configPerSlot, bool clearIt) +{ + pthread_mutex_t *lock = configPerSlot->lock; + configPerSlot->lock = NULL; + if (clearIt) + *configPerSlot->privateNBpdus = 0; + pthread_mutex_unlock(lock); +} + +fapi_nr_ul_config_request_pdu_t *fapiLockIterator(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx) +{ + pthread_mutex_lock(&ul_config->mutex_ul_config); + if (ul_config->number_pdus >= FAPI_NR_UL_CONFIG_LIST_NUM) { + LOG_E(NR_MAC, "Error in ul config in slot %d no memory\n", ul_config->slot); + pthread_mutex_unlock(&ul_config->mutex_ul_config); + return NULL; + } + if (ul_config->number_pdus != 0 && (ul_config->frame != frame_tx || ul_config->slot != slot_tx)) { + LOG_E(NR_MAC, "Error in ul config consistency, clearing it slot %d\n", slot_tx); + ul_config->number_pdus = 0; + pthread_mutex_unlock(&ul_config->mutex_ul_config); + return NULL; + } + if (ul_config->number_pdus >= FAPI_NR_UL_CONFIG_LIST_NUM) { + LOG_E(NR_MAC, "Error in ul config for slot %d, no memory\n", slot_tx); + pthread_mutex_unlock(&ul_config->mutex_ul_config); + return NULL; + } + fapi_nr_ul_config_request_pdu_t *pdu = ul_config->ul_config_list + ul_config->number_pdus; + pdu->pdu_type = FAPI_NR_END; + pdu->lock = &ul_config->mutex_ul_config; + pdu->privateNBpdus = &ul_config->number_pdus; + return ul_config->ul_config_list; +} + +fapi_nr_ul_config_request_pdu_t *lockGet_ul_iterator(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx) +{ + NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon; + //Check if requested on the right slot + AssertFatal(is_nr_UL_slot(tdd_config, slot_tx, mac->frame_type) != 0, "UL config_request called at wrong slot %d\n", slot_tx); + AssertFatal(mac->ul_config_request != NULL, "mac->ul_config_request not initialized, logic bug\n"); + return fapiLockIterator(mac->ul_config_request + slot_tx, frame_tx, slot_tx); } /* @@ -146,10 +173,7 @@ void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf // Table 7.3.1.1.2-2: transformPrecoder=disabled and maxRank = 2 or 3 or 4 if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) - && ((*pusch_Config->maxRank == 2) || - (*pusch_Config->maxRank == 3) || - (*pusch_Config->maxRank == 4))){ - + && ((*pusch_Config->maxRank == 2) || (*pusch_Config->maxRank == 3) || (*pusch_Config->maxRank == 4))) { if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][0]; pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1]; @@ -168,9 +192,8 @@ void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf // Table 7.3.1.1.2-3: transformPrecoder= enabled, or transformPrecoder=disabled and maxRank = 1 if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) - || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) - && (*pusch_Config->maxRank == 1)) { - + || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) + && (*pusch_Config->maxRank == 1)) { if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][6]; pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7]; @@ -206,9 +229,8 @@ void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf // Table 7.3.1.1.2-5: transformPrecoder= enabled, or transformPrecoder= disabled and maxRank = 1 if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) - || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) - && (*pusch_Config->maxRank == 1)) { - + || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) + && (*pusch_Config->maxRank == 1)) { if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][16]; pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17]; @@ -218,7 +240,6 @@ void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][18]; pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19]; } - } } } @@ -251,8 +272,8 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_ if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) && (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-6 - pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; - pusch_config_pdu->dmrs_ports = 1<antenna_ports.val; + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; + pusch_config_pdu->dmrs_ports = 1 << dci->antenna_ports.val; } if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) && @@ -263,8 +284,8 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_ *n_front_load_symb = (dci->antenna_ports.val > 3)?2:1; } - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && - (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-8/9/10/11 + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (dmrs_type == NULL) + && (max_length == NULL)) { // tables 7.3.1.1.2-8/9/10/11 if (rank == 1) { pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; @@ -287,8 +308,8 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_ } } - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && - (dmrs_type == NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-12/13/14/15 + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (dmrs_type == NULL) + && (max_length != NULL)) { // tables 7.3.1.1.2-12/13/14/15 if (rank == 1){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC @@ -324,9 +345,8 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_ } } - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && - (dmrs_type != NULL) && - (max_length == NULL)) { // tables 7.3.1.1.2-16/17/18/19 + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (dmrs_type != NULL) + && (max_length == NULL)) { // tables 7.3.1.1.2-16/17/18/19 if (rank == 1){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?((dci->antenna_ports.val > 5)?3:2):1; //TBC @@ -358,8 +378,8 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_ } } - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && - (dmrs_type != NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-20/21/22/23 + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (dmrs_type != NULL) + && (max_length != NULL)) { // tables 7.3.1.1.2-20/21/22/23 if (rank == 1){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_20[dci->antenna_ports.val][0]; //TBC @@ -373,7 +393,7 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_ //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_21[dci->antenna_ports.val][1]; //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_21[dci->antenna_ports.val][2]; //n_front_load_symb = table_7_3_1_1_2_21[dci->antenna_ports.val][3]; //FIXME - } + } if (rank == 3){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_22[dci->antenna_ports.val][0]; //TBC @@ -440,7 +460,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, int abwp_size = current_UL_BWP->BWPSize; int scs = current_UL_BWP->scs; - // BWP start selection according to 8.3 of TS 38.213 + // BWP start selection according to 8.3 of TS 38.213 if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) { pusch_config_pdu->bwp_start = abwp_start; pusch_config_pdu->bwp_size = abwp_size; @@ -458,8 +478,10 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, mask = (1 << (28 - (int)(ceil(log2((ibwp_size*(ibwp_size+1))>>1))))) - 1; int f_alloc = rar_grant->Msg3_f_alloc & mask; - if (nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, ibwp_size, 0, f_alloc) < 0) + if (nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, ibwp_size, 0, f_alloc) < 0) { + LOG_E(NR_MAC, "can't nr_ue_process_dci_freq_dom_resource_assignment()\n"); return -1; + } // virtual resource block to physical resource mapping for Msg3 PUSCH (6.3.1.7 in 38.211) //pusch_config_pdu->rb_start += ibwp_start - abwp_start; @@ -544,7 +566,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = NULL; if(pusch_Config) { NR_DMRS_ulconfig = (mappingtype == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA) - ? pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; + ? pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup + : pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; } pusch_config_pdu->scid = 0; @@ -572,8 +595,10 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, else AssertFatal(1==0,"SequenceGroupHopping or sequenceHopping are NOT Supported\n"); - LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d \n", pusch_config_pdu->num_dmrs_cdm_grps_no_data, - pusch_config_pdu->dfts_ofdm.low_papr_group_number); + LOG_D(NR_MAC, + "TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d \n", + pusch_config_pdu->num_dmrs_cdm_grps_no_data, + pusch_config_pdu->dfts_ofdm.low_papr_group_number); } else { if (pusch_config_pdu->scid == 0 && NR_DMRS_ulconfig && @@ -589,6 +614,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, /* IDENTIFIER_DCI_FORMATS */ /* FREQ_DOM_RESOURCE_ASSIGNMENT_UL */ if (nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, current_UL_BWP->BWPSize, 0, dci->frequency_domain_assignment.val) < 0){ + LOG_E(NR_MAC, "can't nr_ue_process_dci_freq_dom_resource_assignment()\n"); return -1; } @@ -733,10 +759,11 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, return 0; } -void configure_srs_pdu(NR_UE_MAC_INST_t *mac, - NR_SRS_Resource_t *srs_resource, - fapi_nr_ul_config_srs_pdu *srs_config_pdu, - int period, int offset) +int configure_srs_pdu(NR_UE_MAC_INST_t *mac, + NR_SRS_Resource_t *srs_resource, + fapi_nr_ul_config_srs_pdu *srs_config_pdu, + int period, + int offset) { NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; @@ -804,6 +831,7 @@ void configure_srs_pdu(NR_UE_MAC_INST_t *mac, LOG_I(NR_MAC,"srs_config_pdu->t_srs = %u\n", srs_config_pdu->t_srs); LOG_I(NR_MAC,"srs_config_pdu->t_offset = %u\n", srs_config_pdu->t_offset); #endif + return 0; } // Aperiodic SRS scheduling @@ -860,11 +888,13 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger return; } int sched_frame = frame + (slot + slot_offset >= n_slots_frame) % 1024; - - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, sched_slot, slot_offset); - fapi_nr_ul_config_srs_pdu *srs_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].srs_config_pdu; - configure_srs_pdu(mac, srs_resource, srs_config_pdu, 0, 0); - fill_ul_config(ul_config, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_SRS); + fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_SRS); + if (!pdu) + return; + int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, 0, 0); + if (ret != 0) + remove_ul_config_last_item(pdu); + release_ul_config(pdu, false); } @@ -913,14 +943,15 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo // Check if UE should transmit the SRS if((frame*n_slots_frame+slot-offset)%period == 0) { - - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot, 0); - fapi_nr_ul_config_srs_pdu *srs_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].srs_config_pdu; - - configure_srs_pdu(mac, srs_resource, srs_config_pdu, period, offset); - - fill_ul_config(ul_config, frame, slot, FAPI_NR_UL_CONFIG_TYPE_SRS); - srs_scheduled = true; + fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame, slot, FAPI_NR_UL_CONFIG_TYPE_SRS); + if (!pdu) + return false; + int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, period, offset); + if (ret != 0) + remove_ul_config_last_item(pdu); + else + srs_scheduled = true; + release_ul_config(pdu, false); } } return srs_scheduled; @@ -974,12 +1005,7 @@ void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info) uint32_t gNB_index = ul_info->gNB_index; NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - RA_config_t *ra = &mac->ra; - - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx, 0); - if (!ul_config) - LOG_E(NR_MAC, "mac->ul_config is null!\n"); - + RA_config_t *ra = &mac->ra; if(mac->state < UE_CONNECTED) { nr_ue_get_rach(mod_id, cc_id, frame_tx, gNB_index, slot_tx); nr_ue_prach_scheduler(mod_id, frame_tx, slot_tx); @@ -991,78 +1017,68 @@ void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info) // Schedule ULSCH only if the current frame and slot match those in ul_config_req // AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus) - if (ul_config) { - pthread_mutex_lock(&ul_config->mutex_ul_config); - if (frame_tx == ul_config->frame && ul_config->number_pdus > 0) { + uint8_t ulsch_input_buffer_array[NFAPI_MAX_NUM_UL_PDU][MAX_ULSCH_PAYLOAD_BYTES]; + int number_of_pdus = 0; + + fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = lockGet_ul_iterator(mac, frame_tx, slot_tx); + if (!ulcfg_pdu) + return; + LOG_D(NR_MAC, "number of UL PDUs: %d with UL transmission in sfn [%d.%d]\n", *ulcfg_pdu->privateNBpdus, frame_tx, slot_tx); + + while (ulcfg_pdu->pdu_type != FAPI_NR_END) { + uint8_t *ulsch_input_buffer = ulsch_input_buffer_array[number_of_pdus]; + if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { + int mac_pdu_exist = 0; + uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size; LOG_D(NR_MAC, - "[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", - frame_tx, - slot_tx, - ul_config->number_pdus, - ul_config->frame, - ul_config->slot); - - uint8_t ulsch_input_buffer_array[NFAPI_MAX_NUM_UL_PDU][MAX_ULSCH_PAYLOAD_BYTES]; - int number_of_pdus = 0; - - for (int j = 0; j < ul_config->number_pdus; j++) { - uint8_t *ulsch_input_buffer = ulsch_input_buffer_array[number_of_pdus]; - - fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &ul_config->ul_config_list[j]; - - if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { - int mac_pdu_exist = 0; - uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size; - LOG_D(NR_MAC,"harq_id %d, new_data_indicator %d, TBS_bytes %d (ra_state %d)\n", - ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id, - ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator, - TBS_bytes,ra->ra_state); - if (ra->ra_state == WAIT_RAR && !ra->cfra) { - nr_get_msg3_payload(mod_id, ulsch_input_buffer, TBS_bytes); - for (int k = 0; k < TBS_bytes; k++) { - LOG_D(NR_MAC,"(%i): 0x%x\n", k, ulsch_input_buffer[k]); - } - mac_pdu_exist = 1; - } else { - if (ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator && - (mac->state == UE_CONNECTED || - (ra->ra_state == WAIT_RAR && ra->cfra))){ - // Getting IP traffic to be transmitted - nr_ue_get_sdu(mod_id, cc_id,frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes); - mac_pdu_exist = 1; - } - } - - // Config UL TX PDU - if (mac_pdu_exist) { - ulcfg_pdu->pusch_config_pdu.tx_request_body.pdu = ulsch_input_buffer; - ulcfg_pdu->pusch_config_pdu.tx_request_body.pdu_length = TBS_bytes; - number_of_pdus++; - } - if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra){ - LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 retransmitted\n", frame_tx, slot_tx); - // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 transmission - nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame, ul_info->slot, ul_info->gNB_index); - } - if (ra->ra_state == WAIT_RAR && !ra->cfra){ - LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); - nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, frame_tx, slot_tx, ul_info->gNB_index); - } + "harq_id %d, new_data_indicator %d, TBS_bytes %d (ra_state %d)\n", + ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id, + ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator, + TBS_bytes, + ra->ra_state); + if (ra->ra_state == WAIT_RAR && !ra->cfra) { + nr_get_msg3_payload(mod_id, ulsch_input_buffer, TBS_bytes); + for (int k = 0; k < TBS_bytes; k++) { + LOG_D(NR_MAC, "(%i): 0x%x\n", k, ulsch_input_buffer[k]); + } + mac_pdu_exist = 1; + } else { + if (ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator + && (mac->state == UE_CONNECTED || (ra->ra_state == WAIT_RAR && ra->cfra))) { + // Getting IP traffic to be transmitted + nr_ue_get_sdu(mod_id, cc_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes); + mac_pdu_exist = 1; } } - pthread_mutex_unlock(&ul_config->mutex_ul_config); // avoid double lock - nr_scheduled_response_t scheduled_response = {.ul_config = ul_config, - .mac = mac, - .module_id = ul_info->module_id, - .CC_id = ul_info->cc_id, - .phy_data = ul_info->phy_data}; - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ - LOG_D(NR_MAC,"3# scheduled_response transmitted,%d, %d\n", frame_tx, slot_tx); - mac->if_module->scheduled_response(&scheduled_response); + + // Config UL TX PDU + if (mac_pdu_exist) { + ulcfg_pdu->pusch_config_pdu.tx_request_body.pdu = ulsch_input_buffer; + ulcfg_pdu->pusch_config_pdu.tx_request_body.pdu_length = TBS_bytes; + number_of_pdus++; + } + if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra) { + LOG_I(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 retransmitted\n", frame_tx, slot_tx); + // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 + // transmission + nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame, ul_info->slot, ul_info->gNB_index); + } + if (ra->ra_state == WAIT_RAR && !ra->cfra) { + LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); + nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, frame_tx, slot_tx, ul_info->gNB_index); } - pthread_mutex_lock(&ul_config->mutex_ul_config); } - pthread_mutex_unlock(&ul_config->mutex_ul_config); + ulcfg_pdu++; + } + release_ul_config(ulcfg_pdu, false); + if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL) { + LOG_D(NR_MAC, "3# scheduled_response transmitted,%d, %d\n", frame_tx, slot_tx); + nr_scheduled_response_t scheduled_response = {.ul_config = mac->ul_config_request + slot_tx, + .mac = mac, + .module_id = ul_info->module_id, + .CC_id = ul_info->cc_id, + .phy_data = ul_info->phy_data}; + mac->if_module->scheduled_response(&scheduled_response); } // update Bj for all active lcids before LCP procedure @@ -1125,11 +1141,12 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t uint32_t lcgid_buffer_remain[NR_MAX_NUM_LCGID] = {0,0,0,0,0,0,0,0}; int32_t lcid_bytes_in_buffer[NR_MAX_NUM_LCID]; /* Array for ordering LCID with data per decreasing priority order */ - uint8_t lcid_reordered_array[NR_MAX_NUM_LCID]= - {NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, - NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, - NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, - NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, + uint8_t lcid_reordered_array[NR_MAX_NUM_LCID] = { + NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, + NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, + NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, + NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, + NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, NR_MAX_NUM_LCID, }; uint8_t pos_next = 0; //uint8_t highest_priority = 16; @@ -1219,7 +1236,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t /* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity either the data belongs to a logical channel with higher priority than the priorities of the logical channels which belong to any LCG and for which data is already available for transmission - */ + */ { bsr_regular_triggered = true; LOG_D(NR_MAC, @@ -1761,8 +1778,9 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) AssertFatal(prach_assoc_pattern->prach_conf_period_list[0].nb_of_prach_occasion > 0, "prach_assoc_pattern.prach_conf_period_list[0].nb_of_prach_occasion shouldn't be 0 (nb_tx_ssb %d, ssb_rach_ratio %d)\n", ssb_list->nb_tx_ssb, ssb_rach_ratio); - required_nb_of_prach_conf_period = ((required_nb_of_prach_occasion-1) + prach_assoc_pattern->prach_conf_period_list[0].nb_of_prach_occasion) / - prach_assoc_pattern->prach_conf_period_list[0].nb_of_prach_occasion; + required_nb_of_prach_conf_period = + ((required_nb_of_prach_occasion - 1) + prach_assoc_pattern->prach_conf_period_list[0].nb_of_prach_occasion) + / prach_assoc_pattern->prach_conf_period_list[0].nb_of_prach_occasion; if (required_nb_of_prach_conf_period == 1) { prach_association_period_list->nb_of_prach_conf_period = 1; @@ -2114,8 +2132,6 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, vo if (num_res > 1) multiplex_pucch_resource(mac, pucch, num_res); - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP, 0); - pthread_mutex_lock(&ul_config->mutex_ul_config); for (int j = 0; j < num_res; j++) { if (pucch[j].n_harq + pucch[j].n_sr + pucch[j].n_csi != 0) { LOG_D(NR_MAC, @@ -2128,25 +2144,28 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, vo mac->nr_ue_emul_l1.num_srs = pucch[j].n_sr; mac->nr_ue_emul_l1.num_harqs = pucch[j].n_harq; mac->nr_ue_emul_l1.num_csi_reports = pucch[j].n_csi; - AssertFatal(ul_config->number_pdus < FAPI_NR_UL_CONFIG_LIST_NUM, - "ul_config->number_pdus %d out of bounds\n", - ul_config->number_pdus); - 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); + fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH); + if (!pdu) { + LOG_E(NR_MAC, "Error in pucch allocation\n"); + return; + } 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, - slotP, - mac->crnti, // FIXME not sure this is valid for all pucch instances - &pucch[j], - pucch_pdu); - nr_scheduled_response_t scheduled_response = {.ul_config = ul_config, + int ret = nr_ue_configure_pucch(mac, + slotP, + mac->crnti, // FIXME not sure this is valid for all pucch instances + &pucch[j], + &pdu->pucch_config_pdu); + if (ret != 0) + remove_ul_config_last_item(pdu); + release_ul_config(pdu, false); + } + if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL) { + nr_scheduled_response_t scheduled_response = {.ul_config = mac->ul_config_request + slotP, .mac = mac, .module_id = module_idP, .CC_id = 0 /*TBR fix*/, .phy_data = phy_data}; - if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL) - mac->if_module->scheduled_response(&scheduled_response); + mac->if_module->scheduled_response(&scheduled_response); } } } @@ -2184,19 +2203,20 @@ void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) // As specified in 5.2.2.4 of 38.214 switch (imcsi->csi_IM_ResourceElementPattern->present) { case NR_CSI_IM_Resource__csi_IM_ResourceElementPattern_PR_pattern0: - for (int i = 0; i<4; i++) { - csiim_config_pdu->k_csiim[i] = (imcsi->csi_IM_ResourceElementPattern->choice.pattern0->subcarrierLocation_p0<<1) + (i>>1); - csiim_config_pdu->l_csiim[i] = imcsi->csi_IM_ResourceElementPattern->choice.pattern0->symbolLocation_p0 + (i%2); + for (int i = 0; i < 4; i++) { + csiim_config_pdu->k_csiim[i] = + (imcsi->csi_IM_ResourceElementPattern->choice.pattern0->subcarrierLocation_p0 << 1) + (i >> 1); + csiim_config_pdu->l_csiim[i] = imcsi->csi_IM_ResourceElementPattern->choice.pattern0->symbolLocation_p0 + (i % 2); } break; case NR_CSI_IM_Resource__csi_IM_ResourceElementPattern_PR_pattern1: - for (int i = 0; i<4; i++) { - csiim_config_pdu->k_csiim[i] = (imcsi->csi_IM_ResourceElementPattern->choice.pattern1->subcarrierLocation_p1<<2) + i; + for (int i = 0; i < 4; i++) { + csiim_config_pdu->k_csiim[i] = (imcsi->csi_IM_ResourceElementPattern->choice.pattern1->subcarrierLocation_p1 << 2) + i; csiim_config_pdu->l_csiim[i] = imcsi->csi_IM_ResourceElementPattern->choice.pattern1->symbolLocation_p1; } break; default: - AssertFatal(1==0, "Invalid CSI-IM pattern\n"); + AssertFatal(1 == 0, "Invalid CSI-IM pattern\n"); } dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_CSI_IM; dl_config->number_pdus += 1; @@ -2224,11 +2244,10 @@ NR_CSI_ResourceConfigId_t find_CSI_resourceconfig(NR_CSI_MeasConfig_t *csi_measc AssertFatal(res_list, "nzp_CSI_RS_ResourceSetToAddModList shouldn't be NULL\n"); for (int j = 0; j < res_list->list.count; j++) { NR_NZP_CSI_RS_ResourceSet_t *csi_res = res_list->list.array[j]; - if(*res_id != csi_res->nzp_CSI_ResourceSetId) + if (*res_id != csi_res->nzp_CSI_ResourceSetId) continue; for (int k = 0; k < csi_res->nzp_CSI_RS_Resources.list.count; k++) { - AssertFatal(csi_res->nzp_CSI_RS_Resources.list.array[k], - "NZP_CSI_RS_ResourceId shoulan't be NULL\n"); + AssertFatal(csi_res->nzp_CSI_RS_Resources.list.array[k], "NZP_CSI_RS_ResourceId shoulan't be NULL\n"); if (csi_id == *csi_res->nzp_CSI_RS_Resources.list.array[k]) { found = true; break; @@ -2248,8 +2267,7 @@ NR_CSI_ResourceConfigId_t find_CSI_resourceconfig(NR_CSI_MeasConfig_t *csi_measc return -1; // not found any CSI-resource in current DL BWP associated with this CSI-RS ID } -uint8_t set_csirs_measurement_bitmap(NR_CSI_MeasConfig_t *csi_measconfig, - NR_CSI_ResourceConfigId_t csi_res_id) +uint8_t set_csirs_measurement_bitmap(NR_CSI_MeasConfig_t *csi_measconfig, NR_CSI_ResourceConfigId_t csi_res_id) { uint8_t meas_bitmap = 0; if (csi_res_id > NR_maxNrofCSI_ResourceConfigurations) @@ -2260,27 +2278,26 @@ uint8_t set_csirs_measurement_bitmap(NR_CSI_MeasConfig_t *csi_measconfig, continue; // bit 0 RSRP bit 1 RI bit 2 LI bit 3 PMI bit 4 CQI bit 5 i1 switch (report_config->reportQuantity.present) { - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI : + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI: meas_bitmap += (1 << 1) + (1 << 3) + (1 << 4); break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1 : + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1: meas_bitmap += (1 << 1) + (1 << 5); break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI : + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI: meas_bitmap += (1 << 1) + (1 << 4) + (1 << 5); break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI : + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI: meas_bitmap += (1 << 1) + (1 << 4); break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP : + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: meas_bitmap += 1; break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI : + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI: meas_bitmap += (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4); break; - default : - AssertFatal(false, "Unexpected measurement report type %d\n", - report_config->reportQuantity.present); + default: + AssertFatal(false, "Unexpected measurement report type %d\n", report_config->reportQuantity.present); } } AssertFatal(meas_bitmap > 0, "Expected to have at least 1 measurement configured for CSI-RS\n"); @@ -2311,9 +2328,7 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) csi_period_offset(NULL, nzpcsi->periodicityAndOffset, &period, &offset); if((frame * nr_slots_per_frame[mu] + slot-offset) % period != 0) continue; - NR_CSI_ResourceConfigId_t csi_res_id = find_CSI_resourceconfig(csi_measconfig, - dl_bwp_id, - nzpcsi->nzp_CSI_RS_ResourceId); + NR_CSI_ResourceConfigId_t csi_res_id = find_CSI_resourceconfig(csi_measconfig, dl_bwp_id, nzpcsi->nzp_CSI_RS_ResourceId); // do not schedule reseption of this CSI-RS if not associated with current BWP if(csi_res_id < 0) continue; @@ -2355,23 +2370,23 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) switch(resourceMapping.frequencyDomainAllocation.present){ case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1: csirs_config_pdu->row = 1; - csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0])>>4)&0x0f; + csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]) >> 4) & 0x0f; break; case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2: csirs_config_pdu->row = 2; - csirs_config_pdu->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]>>4)&0x0f) | - ((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<4)&0xff0)); + csirs_config_pdu->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1] >> 4) & 0x0f) + | ((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0] << 4) & 0xff0)); break; case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4: csirs_config_pdu->row = 4; - csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0])>>5)&0x07; + csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0]) >> 5) & 0x07; break; case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other: - csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0])>>2)&0x3f; + csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0]) >> 2) & 0x3f; // determining the row of table 7.4.1.5.3-1 in 38.211 - switch(resourceMapping.nrofPorts){ + switch (resourceMapping.nrofPorts) { case NR_CSI_RS_ResourceMapping__nrofPorts_p1: - AssertFatal(1==0,"Resource with 1 CSI port shouldn't be within other rows\n"); + AssertFatal(1 == 0, "Resource with 1 CSI port shouldn't be within other rows\n"); break; case NR_CSI_RS_ResourceMapping__nrofPorts_p2: csirs_config_pdu->row = 3; @@ -2382,11 +2397,11 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) case NR_CSI_RS_ResourceMapping__nrofPorts_p8: if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) csirs_config_pdu->row = 8; - else{ + else { int num_k = 0; - for (int k=0; k<6; k++) - num_k+=(((csirs_config_pdu->freq_domain)>>k)&0x01); - if(num_k==4) + for (int k = 0; k < 6; k++) + num_k += (((csirs_config_pdu->freq_domain) >> k) & 0x01); + if (num_k == 4) csirs_config_pdu->row = 6; else csirs_config_pdu->row = 7; @@ -2407,7 +2422,7 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) case NR_CSI_RS_ResourceMapping__nrofPorts_p24: if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) csirs_config_pdu->row = 14; - else{ + else { if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) csirs_config_pdu->row = 15; else @@ -2417,19 +2432,19 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) case NR_CSI_RS_ResourceMapping__nrofPorts_p32: if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) csirs_config_pdu->row = 17; - else{ + else { if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) csirs_config_pdu->row = 18; else csirs_config_pdu->row = 16; } break; - default: - AssertFatal(1==0,"Invalid number of ports in CSI-RS resource\n"); + default: + AssertFatal(1 == 0, "Invalid number of ports in CSI-RS resource\n"); } break; default: - AssertFatal(1==0,"Invalid freqency domain allocation in CSI-RS resource\n"); + AssertFatal(1 == 0, "Invalid freqency domain allocation in CSI-RS resource\n"); } dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_CSI_RS; dl_config->number_pdus += 1; @@ -2448,13 +2463,6 @@ static void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_fr if(ra->ra_state != GENERATE_PREAMBLE) return; - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP, 0); - if (!ul_config) { - LOG_E(NR_MAC, "mac->ul_config is null! \n"); - return; - } - - fapi_nr_ul_config_prach_pdu *prach_config_pdu; fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; fapi_nr_prach_config_t *prach_config = &cfg->prach_config; @@ -2486,34 +2494,30 @@ static void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_fr uint16_t format = prach_occasion_info_p->format; uint16_t format0 = format & 0xff; // single PRACH format uint16_t format1 = (format >> 8) & 0xff; // dual PRACH format - 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); - - pthread_mutex_lock(&ul_config->mutex_ul_config); - AssertFatal(ul_config->number_pdusnumber_pdus %d out of bounds\n",ul_config->number_pdus); - prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; - memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); - fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH); - pthread_mutex_unlock(&ul_config->mutex_ul_config); - LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus); - - memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); + fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH); + if (!pdu) { + LOG_E(NR_MAC, "Error in PRACH allocation\n"); + return; + } uint16_t ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); + pdu->prach_config_pdu = (fapi_nr_ul_config_prach_pdu){ + .phys_cell_id = mac->physCellId, + .num_prach_ocas = 1, + .prach_slot = prach_occasion_info_p->slot, + .prach_start_symbol = prach_occasion_info_p->start_symbol, + .num_ra = prach_occasion_info_p->fdm, + .num_cs = ncs, + .root_seq_id = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].prach_root_sequence_index, + .restricted_set = prach_config->restricted_set_config, + .freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1}; - prach_config_pdu->phys_cell_id = mac->physCellId; - prach_config_pdu->num_prach_ocas = 1; - prach_config_pdu->prach_slot = prach_occasion_info_p->slot; - prach_config_pdu->prach_start_symbol = prach_occasion_info_p->start_symbol; - prach_config_pdu->num_ra = prach_occasion_info_p->fdm; - - prach_config_pdu->num_cs = ncs; - prach_config_pdu->root_seq_id = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].prach_root_sequence_index; - prach_config_pdu->restricted_set = prach_config->restricted_set_config; - prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1; - - LOG_I(NR_MAC,"PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", - frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra); + LOG_I(NR_MAC, + "PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", + frameP, + pdu->prach_config_pdu.prach_slot, + pdu->prach_config_pdu.prach_start_symbol, + pdu->prach_config_pdu.num_ra); // Search which SSB is mapped in the RO (among all the SSBs mapped to this RO) for (int ssb_nb_in_ro=0; ssb_nb_in_ronb_mapped_ssb; ssb_nb_in_ro++) { @@ -2525,53 +2529,53 @@ static void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_fr AssertFatal(ra->ssb_nb_in_ronb_mapped_ssb, "%u not found in the mapped SSBs to the PRACH occasion", selected_gnb_ssb_idx); if (format1 != 0xff) { - switch(format0) { // dual PRACH format + switch (format0) { // dual PRACH format case 0xa1: - prach_config_pdu->prach_format = 11; + pdu->prach_config_pdu.prach_format = 11; break; case 0xa2: - prach_config_pdu->prach_format = 12; + pdu->prach_config_pdu.prach_format = 12; break; case 0xa3: - prach_config_pdu->prach_format = 13; + pdu->prach_config_pdu.prach_format = 13; break; - default: - AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); + default: + AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); } } else { - switch(format0) { // single PRACH format + switch (format0) { // single PRACH format case 0: - prach_config_pdu->prach_format = 0; + pdu->prach_config_pdu.prach_format = 0; break; case 1: - prach_config_pdu->prach_format = 1; + pdu->prach_config_pdu.prach_format = 1; break; case 2: - prach_config_pdu->prach_format = 2; + pdu->prach_config_pdu.prach_format = 2; break; case 3: - prach_config_pdu->prach_format = 3; + pdu->prach_config_pdu.prach_format = 3; break; case 0xa1: - prach_config_pdu->prach_format = 4; + pdu->prach_config_pdu.prach_format = 4; break; case 0xa2: - prach_config_pdu->prach_format = 5; + pdu->prach_config_pdu.prach_format = 5; break; case 0xa3: - prach_config_pdu->prach_format = 6; + pdu->prach_config_pdu.prach_format = 6; break; case 0xb1: - prach_config_pdu->prach_format = 7; + pdu->prach_config_pdu.prach_format = 7; break; case 0xb4: - prach_config_pdu->prach_format = 8; + pdu->prach_config_pdu.prach_format = 8; break; case 0xc0: - prach_config_pdu->prach_format = 9; + pdu->prach_config_pdu.prach_format = 9; break; case 0xc2: - prach_config_pdu->prach_format = 10; + pdu->prach_config_pdu.prach_format = 10; break; default: AssertFatal(1 == 0, "Invalid PRACH format"); @@ -2579,10 +2583,11 @@ static void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_fr } // if format1 nr_get_prach_resources(module_idP, 0, 0, &ra->prach_resources, ra->rach_ConfigDedicated); - prach_config_pdu->ra_PreambleIndex = ra->ra_PreambleIndex; - prach_config_pdu->prach_tx_power = get_prach_tx_power(module_idP); - set_ra_rnti(mac, prach_config_pdu); - nr_scheduled_response_t scheduled_response = {.ul_config = ul_config, + pdu->prach_config_pdu.ra_PreambleIndex = ra->ra_PreambleIndex; + pdu->prach_config_pdu.prach_tx_power = get_prach_tx_power(module_idP); + set_ra_rnti(mac, &pdu->prach_config_pdu); + release_ul_config(pdu, false); + nr_scheduled_response_t scheduled_response = {.ul_config = mac->ul_config_request + slotP, .mac = mac, .module_id = module_idP, .CC_id = 0 /*TBR fix*/}; @@ -2611,24 +2616,25 @@ typedef struct { } NR_UE_MAC_CE_INFO; /* -nr_ue_get_sdu_mac_ce_pre finds length in various mac_ce field -Need nothing from mac_ce_p: -Update the following in mac_ce_p: - bsr_len; - bsr_ce_len; - bsr_header_len; - phr_len; TBD - phr_ce_len; TBD - phr_header_len; TBD + nr_ue_get_sdu_mac_ce_pre finds length in various mac_ce field + Need nothing from mac_ce_p: + Update the following in mac_ce_p: + bsr_len; + bsr_ce_len; + bsr_header_len; + phr_len; TBD + phr_ce_len; TBD + phr_header_len; TBD */ int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t subframe, - uint8_t gNB_index, - uint8_t *ulsch_buffer, - uint16_t buflen, - NR_UE_MAC_CE_INFO *mac_ce_p) { + int CC_id, + frame_t frameP, + sub_frame_t subframe, + uint8_t gNB_index, + uint8_t *ulsch_buffer, + uint16_t buflen, + NR_UE_MAC_CE_INFO *mac_ce_p) +{ NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); int num_lcg_id_with_data = 0; @@ -2654,8 +2660,12 @@ int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP, && (mac->scheduling_info.periodicBSR_SF == 0)) { // Trigger BSR Periodic mac->BSR_reporting_active |= NR_BSR_TRIGGER_PERIODIC; - LOG_D(NR_MAC, "[UE %d] MAC BSR Triggered PeriodicBSR Timer expiry at frame%d subframe %d TBS=%d\n", - module_idP, frameP, subframe, buflen); + LOG_D(NR_MAC, + "[UE %d] MAC BSR Triggered PeriodicBSR Timer expiry at frame%d subframe %d TBS=%d\n", + module_idP, + frameP, + subframe, + buflen); } //Compute BSR Length if Regular or Periodic BSR is triggered @@ -2668,13 +2678,13 @@ int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP, //A Regular or Periodic BSR can only be sent if TBS is sufficient as transmitting only a BSR is not allowed if UE has data to transmit if (num_lcg_id_with_data <= 1) { if (buflen >= (sizeof(NR_BSR_SHORT)+sizeof(NR_MAC_SUBHEADER_FIXED)+1)) { - mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); //1 byte - mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte + mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); // 1 byte + mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); // 1 byte } } else { if (buflen >= (num_lcg_id_with_data+1+sizeof(NR_MAC_SUBHEADER_SHORT)+1)) { - mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; //variable size - mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes + mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; // variable size + mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); // 2 bytes } } } @@ -2684,21 +2694,21 @@ int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP, } /* -nr_ue_get_sdu_mac_ce_post recalculates length and prepares the mac_ce field -Need the following from mac_ce_p: - bsr_ce_len - bsr_len - sdu_length_total - total_mac_pdu_header_len -Update the following in mac_ce_p: - bsr_ce_len - bsr_header_len - bsr_len - tot_mac_ce_len - total_mac_pdu_header_len - bsr_s - bsr_l - bsr_t + nr_ue_get_sdu_mac_ce_post recalculates length and prepares the mac_ce field + Need the following from mac_ce_p: + bsr_ce_len + bsr_len + sdu_length_total + total_mac_pdu_header_len + Update the following in mac_ce_p: + bsr_ce_len + bsr_header_len + bsr_len + tot_mac_ce_len + total_mac_pdu_header_len + bsr_s + bsr_l + bsr_t */ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP, int CC_id, @@ -2738,11 +2748,13 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP, // Check BSR padding: it is done after PHR according to Logical Channel Prioritization order // Check for max padding size, ie MAC Hdr for last RLC PDU = 1 /* For Padding BSR: - - if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the size of the Long BSR plus its subheader: - - if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of the LCG with the highest priority logical channel with data available for transmission; + - if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the + size of the Long BSR plus its subheader: + - if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of + the LCG with the highest priority logical channel with data available for transmission; - else report Short BSR. - else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR. - */ + */ if (mac_ce_p->sdu_length_total) { padding_len = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total); } @@ -2760,7 +2772,7 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP, if (num_lcg_id_with_data > 1) { // REPORT SHORT TRUNCATED BSR - //Get LCGID of highest priority LCID with data (todo) + // Get LCGID of highest priority LCID with data (todo) for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) { lcg_id = mac->scheduling_info.lc_sched_info[lcid - 1].LCGID; if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes)) { @@ -2768,7 +2780,7 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP, } } } else { - //Report SHORT BSR, clear bsr_t + // Report SHORT BSR, clear bsr_t mac_ce_p->bsr_t = NULL; } @@ -2849,8 +2861,12 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP, /* Actions when a BSR is sent */ if (mac_ce_p->bsr_ce_len) { - LOG_D(NR_MAC, "[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n", - module_idP, mac_ce_p->bsr_ce_len, mac_ce_p->bsr_header_len, buflen); + LOG_D(NR_MAC, + "[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n", + module_idP, + mac_ce_p->bsr_ce_len, + mac_ce_p->bsr_header_len, + buflen); // Reset ReTx BSR Timer mac->scheduling_info.retxBSR_SF = nr_get_sf_retxBSRTimer(mac->scheduling_info.retxBSR_Timer); LOG_D(NR_MAC, "[UE %d] MAC ReTx BSR Timer Reset =%d\n", module_idP, mac->scheduling_info.retxBSR_SF); @@ -2858,9 +2874,7 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP, // Reset Periodic Timer except when BSR is truncated if ((mac_ce_p->bsr_t == NULL) && (mac->scheduling_info.periodicBSR_Timer != NR_BSR_Config__periodicBSR_Timer_infinity)) { mac->scheduling_info.periodicBSR_SF = nr_get_sf_periodicBSRTimer(mac->scheduling_info.periodicBSR_Timer); - LOG_D(NR_MAC, "[UE %d] MAC Periodic BSR Timer Reset =%d\n", - module_idP, - mac->scheduling_info.periodicBSR_SF); + LOG_D(NR_MAC, "[UE %d] MAC Periodic BSR Timer Reset =%d\n", module_idP, mac->scheduling_info.periodicBSR_SF); } // Reset BSR Trigger flags @@ -3087,7 +3101,7 @@ static bool fill_mac_sdu(module_id_t module_idP, if ((*counter == 0 && lcids_bytes_tot[lcid - 1] >= target) || (count_same_priority_lcids > 1 && lcids_bytes_tot[lcid - 1] >= buflen_ep)) { // only prioritized bit rate should be taken from logical channel in - // the first lcp run except when infinity + // the first lcp run except when infinity LOG_D(NR_MAC, "In %s: total number bytes read from rlc buffer for lcid %d are %d\n", __FUNCTION__, @@ -3101,8 +3115,8 @@ static bool fill_mac_sdu(module_id_t module_idP, /** * Function: to fetch data to be transmitted from RLC, place it in the ULSCH PDU buffer - to generate the complete MAC PDU with sub-headers and MAC CEs according to ULSCH MAC PDU generation (6.1.2 TS 38.321) - the selected sub-header for the payload sub-PDUs is NR_MAC_SUBHEADER_LONG + to generate the complete MAC PDU with sub-headers and MAC CEs according to ULSCH MAC PDU generation (6.1.2 TS 38.321) + the selected sub-header for the payload sub-PDUs is NR_MAC_SUBHEADER_LONG * @module_idP Module ID * @CC_id Component Carrier index * @frameP current UL frame @@ -3157,9 +3171,9 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, uint32_t lcp_allocation_counter = 0; // in the first run all the lc are allocated as per bj and prioritized bit rate but in subsequent runs, no need to consider - // bj and prioritized bit rate but just consider priority + // bj and prioritized bit rate but just consider priority uint16_t buflen_ep = 0; // this variable holds the length in bytes in mac pdu when multiple equal priority channels are present - // because as per standard(TS38.321), all equal priority channels should be served equally + // because as per standard(TS38.321), all equal priority channels should be served equally // nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p); @@ -3173,7 +3187,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, // multiplex in the order of highest priority do { /* - go until there is space availabile in the MAC PDU and there is data available in RLC buffers of active logical channels + go until there is space availabile in the MAC PDU and there is data available in RLC buffers of active logical channels */ uint8_t num_lcids_same_priority = 0; uint8_t count_same_priority_lcids = 0; @@ -3183,10 +3197,10 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, for (uint8_t id = 0; id < avail_lcids_count; id++) { /* - loop over all logical channels in the order of priority. As stated in TS138.321 Section 5.4.3.1, in the first run, only - prioritized number of bytes are taken out from the corresponding RLC buffers of all active logical channels and if there is - still space availble in the MAC PDU, then from the next run all the remaining data from the higher priority logical channel - is placed in the MAC PDU before going on to next high priority logical channel + loop over all logical channels in the order of priority. As stated in TS138.321 Section 5.4.3.1, in the first run, only + prioritized number of bytes are taken out from the corresponding RLC buffers of all active logical channels and if there is + still space availble in the MAC PDU, then from the next run all the remaining data from the higher priority logical channel + is placed in the MAC PDU before going on to next high priority logical channel */ int lcid = lcids_bj_pos[id]; @@ -3225,11 +3239,11 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, while (buflen_remain > 0) { /* - loops until the requested number of bytes from MAC to RLC are placed in the MAC PDU. The number of requested bytes - depends on whether it is the first run or otherwise because in the first run only prioritited number of bytes of all - active logical channels in the order of priority are placed in the MAC PDU. The 'get_num_bytes_to_reqlc' calculates - the target number of bytes to request from RLC via 'mac_rlc_data_req' - */ + loops until the requested number of bytes from MAC to RLC are placed in the MAC PDU. The number of requested bytes + depends on whether it is the first run or otherwise because in the first run only prioritited number of bytes of all + active logical channels in the order of priority are placed in the MAC PDU. The 'get_num_bytes_to_reqlc' calculates + the target number of bytes to request from RLC via 'mac_rlc_data_req' + */ if (!fill_mac_sdu(module_idP, frameP, subframe, @@ -3264,11 +3278,10 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, nr_write_ce_ulsch_pdu(pdu, mac, 0, NULL, mac_ce_p->bsr_t, mac_ce_p->bsr_s, mac_ce_p->bsr_l); pdu += (unsigned char) mac_ce_p->tot_mac_ce_len; - #ifdef ENABLE_MAC_PAYLOAD_DEBUG +#ifdef ENABLE_MAC_PAYLOAD_DEBUG LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len); log_dump(NR_MAC, mac_header_control_elements, mac_ce_p->tot_mac_ce_len, LOG_DUMP_CHAR, "\n"); - #endif - +#endif } buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total); @@ -3280,33 +3293,32 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, ((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING; - #ifdef ENABLE_MAC_PAYLOAD_DEBUG +#ifdef ENABLE_MAC_PAYLOAD_DEBUG LOG_I(NR_MAC, "In %s: padding MAC sub-header with length %ld bytes \n", __FUNCTION__, sizeof(NR_MAC_SUBHEADER_FIXED)); log_dump(NR_MAC, pdu, sizeof(NR_MAC_SUBHEADER_FIXED), LOG_DUMP_CHAR, "\n"); - #endif +#endif pdu++; buflen_remain--; if (IS_SOFTMODEM_RFSIM) { for (int j = 0; j < buflen_remain; j++) { - pdu[j] = (unsigned char) rand(); + pdu[j] = (unsigned char)rand(); } } else { memset(pdu, 0, buflen_remain); } - #ifdef ENABLE_MAC_PAYLOAD_DEBUG +#ifdef ENABLE_MAC_PAYLOAD_DEBUG LOG_I(NR_MAC, "In %s: MAC padding sub-PDU with length %d bytes \n", __FUNCTION__, buflen_remain); log_dump(NR_MAC, pdu, buflen_remain, LOG_DUMP_CHAR, "\n"); - #endif - +#endif } - #ifdef ENABLE_MAC_PAYLOAD_DEBUG +#ifdef ENABLE_MAC_PAYLOAD_DEBUG LOG_I(NR_MAC, "In %s: dumping MAC PDU with length %d: \n", __FUNCTION__, buflen); log_dump(NR_MAC, ulsch_buffer, buflen, LOG_DUMP_CHAR, "\n"); - #endif +#endif return num_sdus > 0 ? 1 : 0; }