Commit 96c506e3 authored by francescomani's avatar francescomani

handling reception of CSI command for aperiodic CSI reporting

parent bba14188
......@@ -251,10 +251,16 @@ typedef struct
typedef struct
{
// payloads with fixed array size
// no place to free the dinamically allocated
// vector without L1 implementation
uint16_t harq_ack_bit_length;
uint8_t harq_payload[4];
uint16_t csi_part1_bit_length;
uint8_t csi_part1_payload[4];
uint16_t csi_part2_bit_length;
uint8_t alpha_scaling;
uint8_t csi_part2_payload[4];
uint8_t alpha_scaling; // 0 = 0.5, 1 = 0.65, 2 = 0.8, 3 = 1
uint8_t beta_offset_harq_ack;
uint8_t beta_offset_csi1;
uint8_t beta_offset_csi2;
......
......@@ -131,6 +131,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
NR_UL_UE_HARQ_t *harq_process_ul_ue = &UE->ul_harq_processes[harq_pid];
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch_ue->pusch_pdu;
AssertFatal(pusch_pdu->pusch_uci.harq_ack_bit_length == 0 &&
pusch_pdu->pusch_uci.csi_part1_bit_length == 0 &&
pusch_pdu->pusch_uci.csi_part2_bit_length == 0,
"UCI on PUSCH not supported\n");
uint32_t tb_size;
// MCS > limit -> retransmission
// Take TB size from previois transmission
......
......@@ -588,10 +588,12 @@ typedef struct NR_UE_UL_BWP {
NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList_Common;
NR_ConfiguredGrantConfig_t *configuredGrantConfig;
NR_PUSCH_Config_t *pusch_Config;
NR_UCI_OnPUSCH_t *uci_onPusch;
NR_PUCCH_Config_t *pucch_Config;
NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon;
long *harq_ACK_SpatialBundlingPUCCH;
NR_CSI_MeasConfig_t *csi_MeasConfig;
NR_CSI_AperiodicTriggerStateList_t *aperiodicTriggerStateList;
NR_SRS_Config_t *srs_Config;
long *msg3_DeltaPreamble;
long transform_precoding;
......
......@@ -5258,7 +5258,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *cs
int csi_resourceidx = 0;
while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) {
csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx];
if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId)
if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId)
found_resource = 1;
csi_resourceidx++;
}
......@@ -5276,7 +5276,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *cs
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId ==
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){
//We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
nb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count;
nb_resources = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count;
csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.array;
csi_report->CSI_Index_list = NULL;
break;
......
......@@ -578,7 +578,17 @@ void configure_current_BWP(NR_UE_MAC_INST_t *mac,
if (cell_group_config->spCellConfig &&
cell_group_config->spCellConfig->spCellConfigDedicated) {
struct NR_ServingCellConfig *spCellConfigDedicated = cell_group_config->spCellConfig->spCellConfigDedicated;
UL_BWP->csi_MeasConfig = spCellConfigDedicated->csi_MeasConfig ? spCellConfigDedicated->csi_MeasConfig->choice.setup : NULL;
if (spCellConfigDedicated->csi_MeasConfig) { // Need M
UL_BWP->csi_MeasConfig = spCellConfigDedicated->csi_MeasConfig->choice.setup;
if (UL_BWP->csi_MeasConfig->aperiodicTriggerStateList &&
UL_BWP->csi_MeasConfig->aperiodicTriggerStateList->present == NR_SetupRelease_CSI_AperiodicTriggerStateList_PR_setup)
UL_BWP->aperiodicTriggerStateList = UL_BWP->csi_MeasConfig->aperiodicTriggerStateList->choice.setup;
else if (UL_BWP->csi_MeasConfig->aperiodicTriggerStateList &&
UL_BWP->csi_MeasConfig->aperiodicTriggerStateList->present == NR_SetupRelease_CSI_AperiodicTriggerStateList_PR_release) {
ASN_STRUCT_FREE(asn_DEF_NR_CSI_AperiodicTriggerStateList, UL_BWP->aperiodicTriggerStateList);
UL_BWP->aperiodicTriggerStateList = NULL;
}
}
UL_BWP->pusch_servingcellconfig =
spCellConfigDedicated->uplinkConfig && spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig ? spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup : NULL;
DL_BWP->pdsch_servingcellconfig = spCellConfigDedicated->pdsch_ServingCellConfig ? spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup : NULL;
......
......@@ -414,9 +414,22 @@ typedef struct ssb_info {
// List of all the possible SSBs and their details
typedef struct ssb_list_info {
ssb_info_t tx_ssb[MAX_NB_SSB];
uint8_t nb_tx_ssb;
uint8_t nb_tx_ssb;
} ssb_list_info_t;
typedef struct csi_payload {
uint32_t part1_payload;
uint32_t part2_payload;
int p1_bits;
int p2_bits;
} csi_payload_t;
typedef enum {
WIDEBAND_ON_PUCCH,
SUBBAND_ON_PUCCH,
ON_PUSCH
} CSI_mapping_t;
/*!\brief Top level UE MAC structure */
typedef struct {
NR_UE_L2_STATE_t state;
......
......@@ -100,6 +100,8 @@ NR_UE_MAC_INST_t *get_mac_inst(
void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info);
void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info);
csi_payload_t nr_ue_aperiodic_csi_reporting(NR_UE_MAC_INST_t *mac, dci_field_t csi_request, int tda, long *K2);
/**\brief fill nr_scheduled_response struct instance
@param nr_scheduled_response_t * pointer to scheduled_response instance to fill
@param fapi_nr_dl_config_request_t* pointer to dl_config,
......@@ -176,28 +178,26 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch);
uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t *pucch,
struct NR_CSI_ReportConfig *csi_reportconfig,
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
NR_CSI_MeasConfig_t *csi_MeasConfig);
csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
struct NR_CSI_ReportConfig *csi_reportconfig,
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
NR_CSI_MeasConfig_t *csi_MeasConfig);
csi_payload_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
struct NR_CSI_ReportConfig *csi_reportconfig,
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
NR_CSI_MeasConfig_t *csi_MeasConfig,
CSI_mapping_t mapping_type);
uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t *pucch,
csi_payload_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
struct NR_CSI_ReportConfig *csi_reportconfig,
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
NR_CSI_MeasConfig_t *csi_MeasConfig);
uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t *pucch,
struct NR_CSI_ReportConfig *csi_reportconfig,
NR_CSI_ResourceConfigId_t csi_ResourceConfigId,
NR_CSI_MeasConfig_t *csi_MeasConfig);
uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t *pucch,
int csi_report_id,
NR_CSI_MeasConfig_t *csi_MeasConfig);
csi_payload_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
int csi_report_id,
CSI_mapping_t mapping_type,
NR_CSI_MeasConfig_t *csi_MeasConfig);
uint8_t get_rsrp_index(int rsrp);
uint8_t get_rsrp_diff_index(int best_rsrp,int current_rsrp);
......@@ -413,6 +413,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
NR_tda_info_t *tda_info,
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
dci_pdu_rel15_t *dci,
csi_payload_t *csi_report,
RAR_grant_t *rar_grant,
uint16_t rnti,
const nr_dci_format_t *dci_format);
......
......@@ -420,11 +420,11 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
NR_tda_info_t *tda_info,
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
dci_pdu_rel15_t *dci,
csi_payload_t *csi_report,
RAR_grant_t *rar_grant,
uint16_t rnti,
const nr_dci_format_t *dci_format)
{
int f_alloc;
int mask;
uint8_t nb_dmrs_re_per_rb;
......@@ -530,6 +530,42 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->tbslbrm = 0;
} else if (dci) {
if (dci->csi_request.nbits > 0 && dci->csi_request.val > 0) {
AssertFatal(csi_report, "CSI report needs to be present in case of CSI request\n");
pusch_config_pdu->pusch_uci.csi_part1_bit_length = csi_report->p1_bits;
int p1_bytes = (csi_report->p1_bits / 8) + (csi_report->p1_bits % 8 > 0);
for (int i = 0; i < p1_bytes; i++)
pusch_config_pdu->pusch_uci.csi_part1_payload[i] = (csi_report->part1_payload >> 8 * i) & 255;
pusch_config_pdu->pusch_uci.csi_part2_bit_length = csi_report->p2_bits;
int p2_bytes = (csi_report->p2_bits / 8) + (csi_report->p2_bits % 8 > 0);
for (int i = 0; i < p2_bytes; i++)
pusch_config_pdu->pusch_uci.csi_part2_payload[i] = (csi_report->part2_payload >> 8 * i) & 255;
AssertFatal(pusch_Config && pusch_Config->uci_OnPUSCH,
"UCI on PUSCH need to be configured\n");
pusch_config_pdu->pusch_uci.alpha_scaling = pusch_Config->uci_OnPUSCH->choice.setup->scaling;
AssertFatal(pusch_Config->uci_OnPUSCH->choice.setup->betaOffsets &&
pusch_Config->uci_OnPUSCH->choice.setup->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic,
"Only semistatic beta offset is supported\n");
NR_BetaOffsets_t *beta_offsets = pusch_Config->uci_OnPUSCH->choice.setup->betaOffsets->choice.semiStatic;
pusch_config_pdu->pusch_uci.beta_offset_harq_ack = pusch_config_pdu->pusch_uci.harq_ack_bit_length < 3 ?
(pusch_config_pdu->pusch_uci.harq_ack_bit_length < 12 ? *beta_offsets->betaOffsetACK_Index2 :
*beta_offsets->betaOffsetACK_Index3) :
*beta_offsets->betaOffsetACK_Index1;
pusch_config_pdu->pusch_uci.beta_offset_csi1 = pusch_config_pdu->pusch_uci.csi_part1_bit_length < 12 ?
*beta_offsets->betaOffsetCSI_Part1_Index1 :
*beta_offsets->betaOffsetCSI_Part1_Index2;
pusch_config_pdu->pusch_uci.beta_offset_csi2 = pusch_config_pdu->pusch_uci.csi_part2_bit_length < 12 ?
*beta_offsets->betaOffsetCSI_Part2_Index1 :
*beta_offsets->betaOffsetCSI_Part2_Index2;
}
else {
pusch_config_pdu->pusch_uci.csi_part1_bit_length = 0;
pusch_config_pdu->pusch_uci.csi_part2_bit_length = 0;
}
pusch_config_pdu->pusch_uci.harq_ack_bit_length = 0;
pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart;
pusch_config_pdu->bwp_size = current_UL_BWP->BWPSize;
......@@ -737,6 +773,48 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
}
csi_payload_t nr_ue_aperiodic_csi_reporting(NR_UE_MAC_INST_t *mac, dci_field_t csi_request, int tda, long *k2)
{
NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP;
NR_CSI_AperiodicTriggerStateList_t *aperiodicTriggerStateList = current_UL_BWP->aperiodicTriggerStateList;
AssertFatal(aperiodicTriggerStateList, "Received CSI request via DCI but aperiodicTriggerStateList is not present\n");
int n_states = aperiodicTriggerStateList->list.count;
int n_ts = csi_request.nbits;
csi_payload_t csi = {0};
AssertFatal(n_states <= ((1 << n_ts) - 1), "Case of subselection indication of trigger states not supported yet\n");
int num_trig = 0;
for (int i = 0; i < n_ts; i++) {
// A non-zero codepoint of the CSI request field in the DCI is mapped to a CSI triggering state
// according to the order of the associated positions of the up to (2^n_ts -1) trigger states
// in CSI-AperiodicTriggerStateList with codepoint 1 mapped to the triggering state in the first position
if (csi_request.val & (1 << i)) {
AssertFatal(num_trig == 0, "Multiplexing more than 1 CSI report is not supported\n");
NR_CSI_AperiodicTriggerState_t *trigger_state = aperiodicTriggerStateList->list.array[i];
AssertFatal(trigger_state->associatedReportConfigInfoList.list.count == 1,
"Cannot handle more than 1 report configuration per state\n");
NR_CSI_AssociatedReportConfigInfo_t *reportconfig = trigger_state->associatedReportConfigInfoList.list.array[0];
NR_CSI_ReportConfigId_t id = reportconfig->reportConfigId;
NR_CSI_MeasConfig_t *csi_measconfig = current_UL_BWP->csi_MeasConfig;
int found = -1;
for (int c = 0; c < csi_measconfig->csi_ReportConfigToAddModList->list.count; c++) {
NR_CSI_ReportConfig_t *report_config = csi_measconfig->csi_ReportConfigToAddModList->list.array[c];
if (report_config->reportConfigId == id) {
struct NR_CSI_ReportConfig__reportConfigType__aperiodic__reportSlotOffsetList *offset_list = &report_config->reportConfigType.choice.aperiodic->reportSlotOffsetList;
AssertFatal(tda < offset_list->list.count, "TDA index from DCI %d exceeds slot offset list %d\n", tda, offset_list->list.count);
if (k2 == NULL || *k2 < *offset_list->list.array[tda])
k2 = offset_list->list.array[tda];
found = c;
break;
}
}
AssertFatal(found >= 0, "Couldn't find csi-ReportConfig with ID %ld\n", id);
num_trig++;
csi = nr_get_csi_payload(mac, found, ON_PUSCH, csi_measconfig);
}
}
return csi;
}
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,
......@@ -2242,7 +2320,7 @@ uint8_t set_csirs_measurement_bitmap(NR_CSI_MeasConfig_t *csi_measconfig,
if (csi_res_id > NR_maxNrofCSI_ResourceConfigurations)
return meas_bitmap; // CSI-RS for tracking
for(int i = 0; i < csi_measconfig->csi_ReportConfigToAddModList->list.count; i++) {
struct NR_CSI_ReportConfig *report_config = csi_measconfig->csi_ReportConfigToAddModList->list.array[i];
NR_CSI_ReportConfig_t *report_config = csi_measconfig->csi_ReportConfigToAddModList->list.array[i];
if(report_config->resourcesForChannelMeasurement != csi_res_id)
continue;
// bit 0 RSRP bit 1 RI bit 2 LI bit 3 PMI bit 4 CQI bit 5 i1
......
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