diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index a7943bb9e52c0f8aa63fb40b6c4b3407d700b547..f14d5220bd852d7a706ae3b20e954cfe9552e160 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h @@ -4060,6 +4060,25 @@ int nfapi_p7_update_checksum(uint8_t* buffer, uint32_t len); */ int nfapi_p7_update_transmit_timestamp(uint8_t* buffer, uint32_t timestamp); +/*! \brief Encodes a nfapi_nr_srs_normalized_channel_iq_matrix_t to a buffer + * + * \param pMessageBuf A pointer to a nfapi_nr_srs_normalized_channel_iq_matrix_t structure + * \param pPackedBuf A pointer to the buffer that the nfapi_nr_srs_normalized_channel_iq_matrix_t will be packed into + * \param packedBufLen The size of the buffer + * \return number of bytes written to the buffer + */ +int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen); + +/*! \brief Decodes a nfapi_nr_srs_normalized_channel_iq_matrix_t from a buffer + * + * \param pMessageBuf A pointer to an encoded nfapi_nr_srs_normalized_channel_iq_matrix_t + * \param messageBufLen The size of the encoded nfapi_nr_srs_normalized_channel_iq_matrix_t + * \param pUnpackedBuf A pointer to the nfapi_nr_srs_normalized_channel_iq_matrix_t + * \param unpackedBufLen The size of nfapi_nr_srs_normalized_channel_iq_matrix_t structure. + * \return 0 means success, -1 means failure. + */ +int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen); + /*! \brief Encodes a nfapi_nr_srs_beamforming_report_t to a buffer * * \param pMessageBuf A pointer to a nfapi_nr_srs_beamforming_report_t structure diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index e3523884d37d77daa8280a7c95878b13f1a9e5da..e183736578c3ec86fb739ca6bd67cc5e0e5c71db 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -3099,6 +3099,40 @@ return 1; //SRS INDICATION +int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen) { + + nfapi_nr_srs_normalized_channel_iq_matrix_t *nr_srs_normalized_channel_iq_matrix = (nfapi_nr_srs_normalized_channel_iq_matrix_t*)pMessageBuf; + + uint8_t *pWritePackedMessage = pPackedBuf; + uint8_t *end = pPackedBuf + packedBufLen; + + if(!(push8(nr_srs_normalized_channel_iq_matrix->normalized_iq_representation, &pWritePackedMessage, end) && + push16(nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements, &pWritePackedMessage, end) && + push16(nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports, &pWritePackedMessage, end) && + push16(nr_srs_normalized_channel_iq_matrix->prg_size, &pWritePackedMessage, end) && + push16(nr_srs_normalized_channel_iq_matrix->num_prgs, &pWritePackedMessage, end))) { + return 0; + } + + uint16_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs*nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports*nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements; + if (nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0) { + channel_matrix_size <<= 1; + } else { + channel_matrix_size <<= 2; + } + + for(int i = 0; i < channel_matrix_size; i++) { + if (!push8(nr_srs_normalized_channel_iq_matrix->channel_matrix[i], &pWritePackedMessage, end)) { + return 0; + } + } + + // Message length + uintptr_t msgHead = (uintptr_t)pPackedBuf; + uintptr_t msgEnd = (uintptr_t)pWritePackedMessage; + return (msgEnd-msgHead); +} + static uint8_t pack_nr_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *prgs, uint8_t **ppWritePackedMsg, uint8_t *end) { if(!push16(prgs->num_prgs, ppWritePackedMsg, end)) { @@ -3114,9 +3148,7 @@ static uint8_t pack_nr_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *prgs, return 1; } -int pack_nr_srs_beamforming_report(void *pMessageBuf, - void *pPackedBuf, - uint32_t packedBufLen) { +int pack_nr_srs_beamforming_report(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen) { nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t*)pMessageBuf; @@ -5850,6 +5882,38 @@ return 1; //SRS INDICATION +int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen) { + + nfapi_nr_srs_normalized_channel_iq_matrix_t *nr_srs_normalized_channel_iq_matrix = (nfapi_nr_srs_normalized_channel_iq_matrix_t*)pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; + + memset(pUnpackedBuf, 0, unpackedBufLen); + + if(!(pull8(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->normalized_iq_representation, end) && + pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements, end) && + pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports, end) && + pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->prg_size, end) && + pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->num_prgs, end))) { + return -1; + } + + uint16_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs*nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports*nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements; + if (nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0) { + channel_matrix_size <<= 1; + } else { + channel_matrix_size <<= 2; + } + + for(int i = 0; i < channel_matrix_size; i++) { + if (!pull8(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->channel_matrix[i], end)) { + return 0; + } + } + + return 0; +} + static uint8_t unpack_nr_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *prgs, uint8_t **ppReadPackedMsg, uint8_t *end) { if(!pull16(ppReadPackedMsg, &prgs->num_prgs, end)) { diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index b5bd6e68ecc8e844360dfc48d5216a637179cf56..ba6c8358e8d7ea7d4959d0ef9ee0fc9a87e17548 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -892,8 +892,26 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { gNB->srs_pdu_list[num_srs].rnti = srs_pdu->rnti; gNB->srs_pdu_list[num_srs].timing_advance_offset = nr_est_timing_advance_srs(&gNB->frame_parms, gNB->nr_srs_info[i]->srs_estimated_channel_time[0]); gNB->srs_pdu_list[num_srs].timing_advance_offset_nsec = (int16_t)(( ((int32_t)gNB->srs_pdu_list[num_srs].timing_advance_offset-31) * ((int32_t)TC_NSEC_x32768) ) >> 15); - gNB->srs_pdu_list[num_srs].srs_usage = srs_pdu->srs_parameters_v4.usage; - gNB->srs_pdu_list[num_srs].report_type = 1; + switch (srs_pdu->srs_parameters_v4.usage) { + case 0: + LOG_W(NR_PHY, "SRS report was not requested by MAC\n"); + return 0; + case 1<<NR_SRS_ResourceSet__usage_beamManagement: + gNB->srs_pdu_list[num_srs].srs_usage = NR_SRS_ResourceSet__usage_beamManagement; + break; + case 1<<NR_SRS_ResourceSet__usage_codebook: + gNB->srs_pdu_list[num_srs].srs_usage = NR_SRS_ResourceSet__usage_codebook; + break; + case 1<<NR_SRS_ResourceSet__usage_nonCodebook: + gNB->srs_pdu_list[num_srs].srs_usage = NR_SRS_ResourceSet__usage_nonCodebook; + break; + case 1<<NR_SRS_ResourceSet__usage_antennaSwitching: + gNB->srs_pdu_list[num_srs].srs_usage = NR_SRS_ResourceSet__usage_antennaSwitching; + break; + default: + LOG_E(NR_PHY, "Invalid srs_pdu->srs_parameters_v4.usage %i\n", srs_pdu->srs_parameters_v4.usage); + } + gNB->srs_pdu_list[num_srs].report_type = srs_pdu->srs_parameters_v4.report_type[0]; #ifdef SRS_IND_DEBUG LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.sfn = %i\n", gNB->UL_INFO.srs_ind.sfn); @@ -909,12 +927,15 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { gNB->srs_pdu_list[num_srs].report_tlv = (nfapi_srs_report_tlv_t*) calloc(1, sizeof(nfapi_srs_report_tlv_t)); } gNB->srs_pdu_list[num_srs].report_tlv->tag = 0; + gNB->srs_pdu_list[num_srs].report_tlv->length = 0; switch (gNB->srs_pdu_list[num_srs].srs_usage) { case NR_SRS_ResourceSet__usage_beamManagement: { - nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t*) calloc(1,sizeof(nfapi_nr_srs_beamforming_report_t)); + nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = + (nfapi_nr_srs_beamforming_report_t*) calloc(1,sizeof(nfapi_nr_srs_beamforming_report_t)); + nr_srs_beamforming_report->prg_size = srs_pdu->beamforming.prg_size; nr_srs_beamforming_report->num_symbols = 1<<srs_pdu->num_symbols; nr_srs_beamforming_report->wide_band_snr = srs_est >= 0 ? (*gNB->nr_srs_info[i]->snr + 64)<<1 : 0xFF; // 0xFF will be set if this field is invalid @@ -947,14 +968,34 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { } case NR_SRS_ResourceSet__usage_codebook: { - gNB->srs_pdu_list[num_srs].report_tlv->length = 0; + + nfapi_nr_srs_normalized_channel_iq_matrix_t *nr_srs_normalized_channel_iq_matrix = + (nfapi_nr_srs_normalized_channel_iq_matrix_t*) calloc(1,sizeof(nfapi_nr_srs_normalized_channel_iq_matrix_t)); + + nr_srs_normalized_channel_iq_matrix->normalized_iq_representation = srs_pdu->srs_parameters_v4.iq_representation; + nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements = gNB->frame_parms.nb_antennas_rx; + nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports = srs_pdu->srs_parameters_v4.num_total_ue_antennas; + nr_srs_normalized_channel_iq_matrix->prg_size = srs_pdu->srs_parameters_v4.prg_size; + nr_srs_normalized_channel_iq_matrix->num_prgs = srs_pdu->srs_parameters_v4.srs_bandwidth_size/srs_pdu->srs_parameters_v4.prg_size; + +#ifdef SRS_IND_DEBUG + LOG_I(NR_PHY, "nr_srs_normalized_channel_iq_matrix->normalized_iq_representation = %i\n", nr_srs_normalized_channel_iq_matrix->normalized_iq_representation); + LOG_I(NR_PHY, "nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements = %i\n", nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements); + LOG_I(NR_PHY, "nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports = %i\n", nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports); + LOG_I(NR_PHY, "nr_srs_normalized_channel_iq_matrix->prg_size = %i\n", nr_srs_normalized_channel_iq_matrix->prg_size); + LOG_I(NR_PHY, "nr_srs_normalized_channel_iq_matrix->num_prgs = %i\n", nr_srs_normalized_channel_iq_matrix->num_prgs); +#endif + + gNB->srs_pdu_list[num_srs].report_tlv->length = pack_nr_srs_normalized_channel_iq_matrix(nr_srs_normalized_channel_iq_matrix, + gNB->srs_pdu_list[num_srs].report_tlv->value, + 16384*sizeof(uint32_t)); + break; } case NR_SRS_ResourceSet__usage_nonCodebook: case NR_SRS_ResourceSet__usage_antennaSwitching: LOG_W(NR_PHY, "PHY procedures for this SRS usage are not implemented yet!\n"); - gNB->srs_pdu_list[num_srs].report_tlv->length = 0; break; default: diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 55e9ff21a74e2403467ece85dc8e8ba024608ecd..cb3a7f2118dd514c408a2b039a4e36d3fc90cbdc 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -532,6 +532,7 @@ typedef enum { typedef struct nr_srs_feedback { uint8_t sri; + uint8_t ul_ri; uint8_t tpmi; } nr_srs_feedback_t; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index 09c1dc17d3a0a672aa04d0a1c7f08f939dc9e5ea..1044072c7aa252a6bd1496fe47d5533878e50b3e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -87,10 +87,17 @@ void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id,NR_U srs_pdu->t_offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p); // TODO: This should be completed - srs_pdu->beamforming.trp_scheme = 0; - srs_pdu->beamforming.num_prgs = m_SRS[srs_pdu->config_index]; - srs_pdu->beamforming.prg_size = 1; - srs_pdu->srs_parameters_v4.usage = srs_resource_set->usage; + srs_pdu->srs_parameters_v4.srs_bandwidth_size = m_SRS[srs_pdu->config_index]; + srs_pdu->srs_parameters_v4.usage = 1<<srs_resource_set->usage; + srs_pdu->srs_parameters_v4.report_type[0] = 1; + srs_pdu->srs_parameters_v4.iq_representation = 1; + srs_pdu->srs_parameters_v4.prg_size = 1; + srs_pdu->srs_parameters_v4.num_total_ue_antennas = 1<<srs_pdu->num_ant_ports; + if (srs_resource_set->usage == NR_SRS_ResourceSet__usage_beamManagement) { + srs_pdu->beamforming.trp_scheme = 0; + srs_pdu->beamforming.num_prgs = m_SRS[srs_pdu->config_index]; + srs_pdu->beamforming.prg_size = 1; + } } void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, sub_frame_t slot, NR_SRS_ResourceSet_t *srs_resource_set, NR_SRS_Resource_t *srs_resource) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 0e470900841d8f817aed5091a0008e743d92a7f2..d075122cfa375bd664bf33abb3d29e5acb51d708 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -792,7 +792,9 @@ void handle_nr_srs_measurements(const module_id_t module_id, case NR_SRS_ResourceSet__usage_beamManagement: { - nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t*) calloc(1,sizeof(nfapi_nr_srs_beamforming_report_t)); + nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = + (nfapi_nr_srs_beamforming_report_t*) calloc(1,sizeof(nfapi_nr_srs_beamforming_report_t)); + unpack_nr_srs_beamforming_report(srs_ind->report_tlv->value, srs_ind->report_tlv->length, nr_srs_beamforming_report, @@ -832,13 +834,39 @@ void handle_nr_srs_measurements(const module_id_t module_id, case NR_SRS_ResourceSet__usage_codebook: { + nfapi_nr_srs_normalized_channel_iq_matrix_t *nr_srs_normalized_channel_iq_matrix = + (nfapi_nr_srs_normalized_channel_iq_matrix_t*) calloc(1,sizeof(nfapi_nr_srs_normalized_channel_iq_matrix_t)); + + unpack_nr_srs_normalized_channel_iq_matrix(srs_ind->report_tlv->value, + srs_ind->report_tlv->length, + nr_srs_normalized_channel_iq_matrix, + sizeof(nfapi_nr_srs_normalized_channel_iq_matrix_t)); + +#ifdef SRS_IND_DEBUG + LOG_I(NR_MAC, "nr_srs_normalized_channel_iq_matrix->normalized_iq_representation = %i\n", nr_srs_normalized_channel_iq_matrix->normalized_iq_representation); + LOG_I(NR_MAC, "nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements = %i\n", nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements); + LOG_I(NR_MAC, "nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports = %i\n", nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports); + LOG_I(NR_MAC, "nr_srs_normalized_channel_iq_matrix->prg_size = %i\n", nr_srs_normalized_channel_iq_matrix->prg_size); + LOG_I(NR_MAC, "nr_srs_normalized_channel_iq_matrix->num_prgs = %i\n", nr_srs_normalized_channel_iq_matrix->num_prgs); + uint16_t *channel_matrix = (uint16_t*)nr_srs_normalized_channel_iq_matrix->channel_matrix; + for(int uI = 0; uI < nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports; uI++) { + for(int gI = 0; gI < nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements; gI++) { + for(int pI = 0; pI < nr_srs_normalized_channel_iq_matrix->num_prgs; pI++) { + uint16_t index = uI*nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements*nr_srs_normalized_channel_iq_matrix->num_prgs + gI*nr_srs_normalized_channel_iq_matrix->num_prgs + pI; + LOG_I(NR_MAC, "(uI %i, gI %i, pI %i) channel_matrix --> real %i, imag %i\n", + uI, gI, pI, channel_matrix[(index<<1)], channel_matrix[(index<<1)+1]); + } + } + } +#endif + // TODO: This should be improved NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; ps->srs_feedback.sri = NR_SRS_SRI_0; + ps->srs_feedback.ul_ri = 0; ps->srs_feedback.tpmi = 0; - uint8_t ul_ri = 0; - sprintf(stats->srs_stats,"UL-RI %d, TPMI %d", ul_ri+1, ps->srs_feedback.tpmi); + sprintf(stats->srs_stats,"UL-RI %d, TPMI %d", ps->srs_feedback.ul_ri+1, ps->srs_feedback.tpmi); break; }