From 37b63f32c07ea4386c54500ce1001cf38ff2f66a Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 26 May 2022 17:50:56 +0100 Subject: [PATCH 01/30] Implementation of compute_srs_resource_indicator function to be improved in future commits --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 127 ++++++++++-------- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 5 + openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 1 + .../NR_MAC_gNB/gNB_scheduler_primitives.c | 14 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 + openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + 6 files changed, 95 insertions(+), 55 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 9a0a4f5ae7..c6a4196369 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2615,6 +2615,64 @@ uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config, return n_antenna_port; } +uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, + NR_PUSCH_Config_t *pusch_Config, + NR_SRS_Config_t *srs_config, + uint16_t *val) { + uint8_t nbits = 0; + + if (srs_config && pusch_Config && pusch_Config->txConfig != NULL) { + + int count=0; + if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook) { + for (int i=0; isrs_ResourceSetToAddModList->list.count; i++) { + if (srs_config->srs_ResourceSetToAddModList->list.array[i]->usage == NR_SRS_ResourceSet__usage_codebook) + count++; + } + if (count>1) { + nbits = 1; + } + } else { + int lmin = 0; + int Lmax = 0; + int lsum = 0; + if (uplinkConfig && uplinkConfig->pusch_ServingCellConfig != NULL) { + if (uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers != NULL) { + Lmax = *uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers; + } else { + AssertFatal(1==0,"MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); + } + } else { + AssertFatal(1==0,"MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); + } + for (int i=0; isrs_ResourceSetToAddModList->list.count; i++) { + if (srs_config->srs_ResourceSetToAddModList->list.array[i]->usage == NR_SRS_ResourceSet__usage_nonCodebook) { + count++; + } + if (count < Lmax) { + lmin = count; + } else { + lmin = Lmax; + } + for (int k=1;k<=lmin;k++) { + lsum += binomial(count,k); + } + } + nbits = (int)ceil(log2(lsum)); + } + + } else { + nbits = 0; + } + + // TODO: Implement this. + if (val) { + *val = 0; + } + + return nbits; +} + uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, const NR_BWP_UplinkCommon_t *initialUplinkBWP, const NR_CellGroupConfig_t *cg, @@ -2631,6 +2689,11 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, long rbg_size_config; int num_entries = 0; + NR_UplinkConfig_t *uplinkConfig = NULL; + if (cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated) { + uplinkConfig = cg->spCellConfig->spCellConfigDedicated->uplinkConfig; + } + const NR_BWP_DownlinkDedicated_t *bwpd = NULL; const NR_BWP_UplinkDedicated_t *ubwpd = NULL; const NR_BWP_DownlinkCommon_t *bwpc = NULL; @@ -2642,23 +2705,21 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, NR_SRS_Config_t *srs_config = NULL; if(bwp_id > 0) { AssertFatal(cg!=NULL,"Cellgroup is null and bwp_id!=0"); - bwpd=cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated; - bwpc=cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Common; - ubwpd=cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated; - ubwpc=cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Common; + bwpd = cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated; + bwpc = cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Common; + ubwpd = uplinkConfig ? uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated : NULL; + ubwpc = uplinkConfig ? uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Common : NULL; pdsch_Config = (bwpd->pdsch_Config) ? bwpd->pdsch_Config->choice.setup : NULL; pdcch_Config = (bwpd->pdcch_Config) ? bwpd->pdcch_Config->choice.setup : NULL; pucch_Config = (ubwpd->pucch_Config) ? ubwpd->pucch_Config->choice.setup : NULL; pusch_Config = (ubwpd->pusch_Config) ? ubwpd->pusch_Config->choice.setup : NULL; srs_config = (ubwpd->srs_Config) ? ubwpd->srs_Config->choice.setup : NULL; - } - else if (cg){ + } else if (cg) { bwpc = initialDownlinkBWP; ubwpc = initialUplinkBWP; bwpd = cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated ? cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL; - ubwpd = cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; + ubwpd = uplinkConfig ? uplinkConfig->initialUplinkBWP : NULL; pdsch_Config = (bwpd && bwpd->pdsch_Config) ? bwpd->pdsch_Config->choice.setup : NULL; pdcch_Config = (bwpd && bwpd->pdcch_Config) ? bwpd->pdcch_Config->choice.setup : NULL; pucch_Config = (ubwpd && ubwpd->pucch_Config) ? ubwpd->pucch_Config->choice.setup : NULL; @@ -2756,55 +2817,15 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, size += dci_pdu->dai[1].nbits; } // SRS resource indicator - if (srs_config && - pusch_Config && - pusch_Config->txConfig != NULL){ - int count=0; - if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook){ - for (int i=0; isrs_ResourceSetToAddModList->list.count; i++) { - if (srs_config->srs_ResourceSetToAddModList->list.array[i]->usage == NR_SRS_ResourceSet__usage_codebook) - count++; - } - if (count>1) { - dci_pdu->srs_resource_indicator.nbits = 1; - size += dci_pdu->srs_resource_indicator.nbits; - } - } - else { - int lmin,Lmax = 0; - int lsum = 0; - if ( cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig != NULL) { - if ( cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers != NULL) - Lmax = *cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers; - else - AssertFatal(1==0,"MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); - } - else - AssertFatal(1==0,"MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); - for (int i=0; isrs_ResourceSetToAddModList->list.count; i++) { - if (srs_config->srs_ResourceSetToAddModList->list.array[i]->usage == NR_SRS_ResourceSet__usage_nonCodebook) - count++; - if (count < Lmax) lmin = count; - else lmin = Lmax; - for (int k=1;k<=lmin;k++) { - lsum += binomial(count,k); - } - } - dci_pdu->srs_resource_indicator.nbits = (int)ceil(log2(lsum)); - size += dci_pdu->srs_resource_indicator.nbits; - } - } else dci_pdu->srs_resource_indicator.nbits = 0; - LOG_D(NR_MAC,"dci_pdu->srs_resource_indicator.nbits %d\n",dci_pdu->srs_resource_indicator.nbits); + dci_pdu->srs_resource_indicator.nbits = compute_srs_resource_indicator(uplinkConfig, pusch_Config, srs_config, NULL); + size += dci_pdu->srs_resource_indicator.nbits; + LOG_D(NR_MAC,"dci_pdu->srs_resource_indicator.nbits %d\n", dci_pdu->srs_resource_indicator.nbits); // Precoding info and number of layers long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwpd, (uint8_t*)&format, rnti_type, 0); - uint8_t pusch_antenna_ports = get_pusch_nb_antenna_ports(pusch_Config, srs_config, dci_pdu->srs_resource_indicator); - dci_pdu->precoding_information.nbits=0; - if (pusch_Config && - pusch_Config->txConfig != NULL){ - if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook){ + if (pusch_Config && pusch_Config->txConfig != NULL) { + if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook) { if (pusch_antenna_ports > 1) { if (pusch_antenna_ports == 4) { if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank>1)) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index ae6d1839b3..d017d2f5c9 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -47,6 +47,11 @@ int is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,slo int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP, frame_type_t frame_type); +uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, + NR_PUSCH_Config_t *pusch_Config, + NR_SRS_Config_t *srs_config, + uint16_t *val); + uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDLBWP, const NR_BWP_UplinkCommon_t *initialULBWP, const NR_CellGroupConfig_t *cg, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 9ac9f0d880..847e42ce96 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -888,6 +888,7 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t ubwp, ubwpd, scc, + NULL, pusch_pdu, &uldci_payload, NR_UL_DCI_FORMAT_0_0, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 27d44755e4..8491ce1f21 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -992,6 +992,7 @@ void config_uldci(const NR_SIB1_t *sib1, const NR_BWP_Uplink_t *ubwp, const NR_BWP_UplinkDedicated_t *ubwpd, const NR_ServingCellConfigCommon_t *scc, + const NR_CellGroupConfig_t *cg, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, int dci_format, @@ -1035,7 +1036,14 @@ void config_uldci(const NR_SIB1_t *sib1, ubwpd2->pusch_Config->choice.setup->txConfig != NULL) { AssertFatal(*ubwpd2->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook, "Non Codebook configuration non supported\n"); - dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS + NR_UplinkConfig_t *uplinkConfig = NULL; + if (cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated) { + uplinkConfig = cg->spCellConfig->spCellConfigDedicated->uplinkConfig; + } + compute_srs_resource_indicator(uplinkConfig, + ubwpd->pusch_Config ? ubwpd->pusch_Config->choice.setup : NULL, + ubwpd2 && ubwpd2->srs_Config ? ubwpd->srs_Config->choice.setup : NULL, + &dci_pdu_rel15->srs_resource_indicator.val); } dci_pdu_rel15->precoding_information.val= 0; if (pusch_pdu->nrOfLayers == 2) @@ -1534,8 +1542,10 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, int dci_size = nr_dci_size(scc->downlinkConfigCommon->initialDownlinkBWP,scc->uplinkConfigCommon->initialUplinkBWP, CellGroup, dci_pdu_rel15, dci_format, rnti_type, N_RB, bwp_id, coreset_id, cset0_bwp_size); pdcch_dci_pdu->PayloadSizeBits = dci_size; AssertFatal(dci_size <= 64, "DCI sizes above 64 bits not yet supported"); - if (dci_format == NR_DL_DCI_FORMAT_1_1 || dci_format == NR_UL_DCI_FORMAT_0_1) + + if (dci_format == NR_DL_DCI_FORMAT_1_1 || dci_format == NR_UL_DCI_FORMAT_0_1) { prepare_dci(CellGroup, dci_pdu_rel15, dci_format, bwp_id); + } /// Payload generation switch (dci_format) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 38e6ca0d6f..46fc6cf738 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1989,6 +1989,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) sched_ctrl->active_ubwp, ubwpd, scc, + cg, pusch_pdu, &uldci_payload, ps->dci_format, @@ -1996,6 +1997,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) UE_info->UE_sched_ctrl[UE_id].tpc0, n_ubwp, bwp_id); + fill_dci_pdu_rel15(scc, cg, dci_pdu, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index e16f387b50..bde9b09552 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -195,6 +195,7 @@ void config_uldci(const NR_SIB1_t *sib1, const NR_BWP_Uplink_t *ubwp, const NR_BWP_UplinkDedicated_t *ubwpd, const NR_ServingCellConfigCommon_t *scc, + const NR_CellGroupConfig_t *cg, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, int dci_format, From ed917dbdd6abe5163d0ac16c548589b0cead0d67 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 26 May 2022 19:39:05 +0100 Subject: [PATCH 02/30] Fixes in compute_srs_resource_indicator function --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index c6a4196369..e25ed33588 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2615,7 +2615,7 @@ uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config, return n_antenna_port; } -uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, +uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, uint16_t *val) { @@ -2623,19 +2623,35 @@ uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, if (srs_config && pusch_Config && pusch_Config->txConfig != NULL) { - int count=0; if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook) { + + // TS 38.212 - Section 7.3.1.1.2: SRS resource indicator has ceil(log2(N_SRS)) bits according to + // Tables 7.3.1.1.2-32, 7.3.1.1.2-32A and 7.3.1.1.2-32B if the higher layer parameter txConfig = codebook, + // where N_SRS is the number of configured SRS resources in the SRS resource set configured by higher layer + // parameter srs-ResourceSetToAddModList, and associated with the higher layer parameter usage of value codeBook. + int count = 0; for (int i=0; isrs_ResourceSetToAddModList->list.count; i++) { - if (srs_config->srs_ResourceSetToAddModList->list.array[i]->usage == NR_SRS_ResourceSet__usage_codebook) + if (srs_config->srs_ResourceSetToAddModList->list.array[i]->usage == NR_SRS_ResourceSet__usage_codebook) { count++; + } } - if (count>1) { - nbits = 1; + if (count>0) { + nbits = ceil(log2(count)); } + } else { - int lmin = 0; + + // TS 38.212 - Section 7.3.1.1.2: SRS resource indicator has ceil(log2(sum(k = 1 until min(Lmax,N_SRS) of binomial(N_SRS,k)))) + // bits according to Tables 7.3.1.1.2-28/29/30/31 if the higher layer parameter txConfig = nonCodebook, where + // N_SRS is the number of configured SRS resources in the SRS resource set configured by higher layer parameter + // srs-ResourceSetToAddModList, and associated with the higher layer parameter usage of value nonCodeBook and: + // + // - if UE supports operation with maxMIMO-Layers and the higher layer parameter maxMIMO-Layers of + // PUSCH-ServingCellConfig of the serving cell is configured, Lmax is given by that parameter; + // + // - otherwise, Lmax is given by the maximum number of layers for PUSCH supported by the UE for the serving cell + // for non-codebook based operation. int Lmax = 0; - int lsum = 0; if (uplinkConfig && uplinkConfig->pusch_ServingCellConfig != NULL) { if (uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers != NULL) { Lmax = *uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers; @@ -2645,24 +2661,23 @@ uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, } else { AssertFatal(1==0,"MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); } + int lmin = 0; + int lsum = 0; + int count = 0; for (int i=0; isrs_ResourceSetToAddModList->list.count; i++) { if (srs_config->srs_ResourceSetToAddModList->list.array[i]->usage == NR_SRS_ResourceSet__usage_nonCodebook) { count++; } - if (count < Lmax) { - lmin = count; - } else { - lmin = Lmax; - } - for (int k=1;k<=lmin;k++) { - lsum += binomial(count,k); - } } - nbits = (int)ceil(log2(lsum)); + lmin = count < Lmax ? count : Lmax; + for (int k=1;k<=lmin;k++) { + lsum += binomial(count,k); + } + if (lsum>0) { + nbits = ceil(log2(lsum)); + } } - } else { - nbits = 0; } // TODO: Implement this. From 8c517c677903fca53d3e55874e1445cdef90d78f Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 26 May 2022 20:18:10 +0100 Subject: [PATCH 03/30] Add debug logs --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index e25ed33588..26a6b90ef7 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2615,16 +2615,31 @@ uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config, return n_antenna_port; } +//#define DEBUG_SRS_RESOURCE_IND uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, uint16_t *val) { uint8_t nbits = 0; + // SRI occupies a number of bits which is dependent upon the uplink transmission scheme, and it is used to determine + // the antenna ports and uplink transmission beam to use for PUSCH transmission. In the case of codebook based + // transmission, the SRI is used to select between SRS Resources belonging to different antenna panels + // (kind of directional antenna). There can be up to 2 SRS Resources (2 antenna panels). In the case of non-codebook + // based transmission, the SRI is used to select one or more SRS Resources from a set of N_SRS resources. The number + // of SRS Resources selected corresponds to the number of layers (rank) to be transmitted. For now, we set SRI = 0. + if (val) { + *val = 0; + } + if (srs_config && pusch_Config && pusch_Config->txConfig != NULL) { if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook) { +#ifdef DEBUG_SRS_RESOURCE_IND + LOG_I(NR_MAC, "*pusch_Config->txConfig = NR_PUSCH_Config__txConfig_codebook\n"); +#endif + // TS 38.212 - Section 7.3.1.1.2: SRS resource indicator has ceil(log2(N_SRS)) bits according to // Tables 7.3.1.1.2-32, 7.3.1.1.2-32A and 7.3.1.1.2-32B if the higher layer parameter txConfig = codebook, // where N_SRS is the number of configured SRS resources in the SRS resource set configured by higher layer @@ -2639,8 +2654,17 @@ uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, nbits = ceil(log2(count)); } +#ifdef DEBUG_SRS_RESOURCE_IND + LOG_I(NR_MAC, "srs_config->srs_ResourceSetToAddModList->list.count = %i\n", srs_config->srs_ResourceSetToAddModList->list.count); + LOG_I(NR_MAC, "count = %i\n", count); +#endif + } else { +#ifdef DEBUG_SRS_RESOURCE_IND + LOG_I(NR_MAC, "*pusch_Config->txConfig = NR_PUSCH_Config__txConfig_nonCodebook\n"); +#endif + // TS 38.212 - Section 7.3.1.1.2: SRS resource indicator has ceil(log2(sum(k = 1 until min(Lmax,N_SRS) of binomial(N_SRS,k)))) // bits according to Tables 7.3.1.1.2-28/29/30/31 if the higher layer parameter txConfig = nonCodebook, where // N_SRS is the number of configured SRS resources in the SRS resource set configured by higher layer parameter @@ -2676,13 +2700,15 @@ uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, if (lsum>0) { nbits = ceil(log2(lsum)); } + +#ifdef DEBUG_SRS_RESOURCE_IND + LOG_I(NR_MAC, "srs_config->srs_ResourceSetToAddModList->list.count = %i\n", srs_config->srs_ResourceSetToAddModList->list.count); + LOG_I(NR_MAC, "count = %i\n", count); + LOG_I(NR_MAC, "Lmax = %i\n", Lmax); + LOG_I(NR_MAC, "lsum = %i\n", lsum); +#endif + } - - } - - // TODO: Implement this. - if (val) { - *val = 0; } return nbits; @@ -2834,7 +2860,7 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, // SRS resource indicator dci_pdu->srs_resource_indicator.nbits = compute_srs_resource_indicator(uplinkConfig, pusch_Config, srs_config, NULL); size += dci_pdu->srs_resource_indicator.nbits; - LOG_D(NR_MAC,"dci_pdu->srs_resource_indicator.nbits %d\n", dci_pdu->srs_resource_indicator.nbits); + LOG_W(NR_MAC,"dci_pdu->srs_resource_indicator.nbits %d\n", dci_pdu->srs_resource_indicator.nbits); // Precoding info and number of layers long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwpd, (uint8_t*)&format, rnti_type, 0); uint8_t pusch_antenna_ports = get_pusch_nb_antenna_ports(pusch_Config, srs_config, dci_pdu->srs_resource_indicator); From 762eba239e021e21a59c914e1e21b66b781faef9 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 30 May 2022 15:28:03 +0100 Subject: [PATCH 04/30] Implementation of tables and get values to SRS resource indicator --- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 23 ++++++++ openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 54 +++++++++++++++++-- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 1 + openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 1 + .../NR_MAC_gNB/gNB_scheduler_primitives.c | 2 + .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 7 +++ openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 1 + 8 files changed, 87 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 9123afd324..55e9ff21a7 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -512,5 +512,28 @@ typedef struct Type0_PDCCH_CSS_config_s { bool active; } NR_Type0_PDCCH_CSS_config_t; +typedef enum { + NR_SRS_SRI_0 = 0, + NR_SRS_SRI_1, + NR_SRS_SRI_2, + NR_SRS_SRI_3, + NR_SRS_SRI_0_1, + NR_SRS_SRI_0_2, + NR_SRS_SRI_0_3, + NR_SRS_SRI_1_2, + NR_SRS_SRI_1_3, + NR_SRS_SRI_2_3, + NR_SRS_SRI_0_1_2, + NR_SRS_SRI_0_1_3, + NR_SRS_SRI_0_2_3, + NR_SRS_SRI_1_2_3, + NR_SRS_SRI_0_1_2_3 +} nr_srs_sri_t; + +typedef struct nr_srs_feedback { + uint8_t sri; + uint8_t tpmi; +} nr_srs_feedback_t; + #endif /*__LAYER2_MAC_H__ */ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 474071b0bb..d449caadc9 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1956,6 +1956,32 @@ int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = { {0, 3072, -1, -1, 3, 1539, -1, -1}, //14 // (DMRS l' position) }; +// TS 38.212 +uint16_t table_7_3_1_1_2_28[3][15] = { + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; +uint16_t table_7_3_1_1_2_29[3][15] = { + {0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 2, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0}, +}; +uint16_t table_7_3_1_1_2_30[3][15] = { + {0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 2, 0, 3, 4, 0, 5, 0, 0, 6, 0, 0, 0, 0}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0}, +}; +uint16_t table_7_3_1_1_2_31[3][15] = { + {0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 2, 0, 3, 4, 0, 5, 0, 0, 6, 0, 0, 0, 0}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, +}; +uint16_t table_7_3_1_1_2_32[3][15] = { + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; void get_delta_arfcn(int i, uint32_t nrarfcn, uint64_t N_OFFs){ @@ -2617,6 +2643,7 @@ uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config, uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, + nr_srs_feedback_t *srs_feedback, uint16_t *val) { uint8_t nbits = 0; @@ -2625,7 +2652,7 @@ uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, // transmission, the SRI is used to select between SRS Resources belonging to different antenna panels // (kind of directional antenna). There can be up to 2 SRS Resources (2 antenna panels). In the case of non-codebook // based transmission, the SRI is used to select one or more SRS Resources from a set of N_SRS resources. The number - // of SRS Resources selected corresponds to the number of layers (rank) to be transmitted. For now, we set SRI = 0. + // of SRS Resources selected corresponds to the number of layers (rank) to be transmitted. if (val) { *val = 0; } @@ -2650,6 +2677,9 @@ uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, } if (count>0) { nbits = ceil(log2(count)); + if (val && srs_feedback && nbits > 0) { + *val = table_7_3_1_1_2_32[count-2][srs_feedback->sri]; + } } #ifdef DEBUG_SRS_RESOURCE_IND @@ -2697,6 +2727,24 @@ uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, } if (lsum>0) { nbits = ceil(log2(lsum)); + if (val && srs_feedback && nbits > 0) { + switch(Lmax) { + case 1: + *val = table_7_3_1_1_2_28[count-2][srs_feedback->sri]; + break; + case 2: + *val = table_7_3_1_1_2_29[count-2][srs_feedback->sri]; + break; + case 3: + *val = table_7_3_1_1_2_30[count-2][srs_feedback->sri]; + break; + case 4: + *val = table_7_3_1_1_2_31[count-2][srs_feedback->sri]; + break; + default: + LOG_E(NR_MAC, "%s (%d) - Invalid Lmax %d\n", __FUNCTION__, __LINE__, Lmax); + } + } } #ifdef DEBUG_SRS_RESOURCE_IND @@ -2856,9 +2904,9 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, size += dci_pdu->dai[1].nbits; } // SRS resource indicator - dci_pdu->srs_resource_indicator.nbits = compute_srs_resource_indicator(uplinkConfig, pusch_Config, srs_config, NULL); + dci_pdu->srs_resource_indicator.nbits = compute_srs_resource_indicator(uplinkConfig, pusch_Config, srs_config, NULL, NULL); size += dci_pdu->srs_resource_indicator.nbits; - LOG_W(NR_MAC,"dci_pdu->srs_resource_indicator.nbits %d\n", dci_pdu->srs_resource_indicator.nbits); + LOG_D(NR_MAC,"dci_pdu->srs_resource_indicator.nbits %d\n", dci_pdu->srs_resource_indicator.nbits); // Precoding info and number of layers long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwpd, (uint8_t*)&format, rnti_type, 0); uint8_t pusch_antenna_ports = get_pusch_nb_antenna_ports(pusch_Config, srs_config, dci_pdu->srs_resource_indicator); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 325e303b15..c251c8c59b 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -50,6 +50,7 @@ int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, sl uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, + nr_srs_feedback_t *srs_feedback, uint16_t *val); uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDLBWP, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index e0d0f40209..e3203deb12 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -888,6 +888,7 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t NULL, pusch_pdu, &uldci_payload, + NULL, NR_UL_DCI_FORMAT_0_0, ra->Msg3_tda_id, ra->msg3_TPC, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 3666fddbf2..fc5e374ebf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1033,6 +1033,7 @@ void config_uldci(const NR_SIB1_t *sib1, const NR_CellGroupConfig_t *cg, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, + nr_srs_feedback_t *srs_feedback, int dci_format, int time_domain_assignment, uint8_t tpc, @@ -1081,6 +1082,7 @@ void config_uldci(const NR_SIB1_t *sib1, compute_srs_resource_indicator(uplinkConfig, ubwpd->pusch_Config ? ubwpd->pusch_Config->choice.setup : NULL, ubwpd2 && ubwpd2->srs_Config ? ubwpd->srs_Config->choice.setup : NULL, + srs_feedback, &dci_pdu_rel15->srs_resource_indicator.val); } dci_pdu_rel15->precoding_information.val= 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index dee57f7fb2..4515f9f5fd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -809,6 +809,12 @@ void handle_nr_srs_measurements(const module_id_t module_id, } LOG_D(NR_MAC, "ulprbbl[%3i] = 0x%x\n", rb, ulprbbl[rb]); } + + // TODO: This should be improved + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; + ps->srs_feedback.sri = NR_SRS_SRI_0; + ps->srs_feedback.tpmi = 0; } long get_K2(NR_ServingCellConfigCommon_t *scc, @@ -1879,6 +1885,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) cg, pusch_pdu, &uldci_payload, + &ps->srs_feedback, ps->dci_format, ps->time_domain_allocation, UE_info->UE_sched_ctrl[UE_id].tpc0, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index bc0b9b8a10..71e9f5bf0d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -198,6 +198,7 @@ void config_uldci(const NR_SIB1_t *sib1, const NR_CellGroupConfig_t *cg, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, + nr_srs_feedback_t *srs_feedback, int dci_format, int time_domain_assignment, uint8_t tpc, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 478200a347..034eba6b0c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -348,6 +348,7 @@ typedef struct NR_pusch_semi_static_t { int dci_format; int time_domain_allocation; uint8_t nrOfLayers; + nr_srs_feedback_t srs_feedback; uint8_t num_dmrs_cdm_grps_no_data; int startSymbolIndex; From d6e960e4d7de0dda45fd680ba33e576988f8fad5 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 30 May 2022 20:50:00 +0100 Subject: [PATCH 05/30] Implementation of tables and get values to precoding information --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 286 ++++++++++++++++-- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 7 + .../NR_MAC_gNB/gNB_scheduler_primitives.c | 15 +- 3 files changed, 275 insertions(+), 33 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index d449caadc9..da38543f14 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1957,6 +1957,20 @@ int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = { }; // TS 38.212 +uint16_t table_7_3_1_1_2_2_1layer[28] = {0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}; +uint16_t table_7_3_1_1_2_2_2layers[22] = {4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 25, 26, 27, 48, 49, 50, 51, 52, 53, 54, 55}; +uint16_t table_7_3_1_1_2_2_3layers[7] = {10, 28, 29, 56, 57, 58, 59}; +uint16_t table_7_3_1_1_2_2_4layers[5] = {11, 30, 31, 60, 61}; +uint16_t table_7_3_1_1_2_2B_1layer[16] = {0, 1, 2, 3, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 24, 25}; +uint16_t table_7_3_1_1_2_2B_2layers[14] = {4, 5, 6, 7, 8, 9, 13, 26, 27, 28, 29, 30, 31, 32}; +uint16_t table_7_3_1_1_2_2B_3layers[3] = {10, 14, 33}; +uint16_t table_7_3_1_1_2_2B_4layers[3] = {11, 34, 35}; +uint16_t table_7_3_1_1_2_2A_1layer[16] = {0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 20, 10, 21, 22}; +uint16_t table_7_3_1_1_2_2A_2layers[14] = {4, 5, 6, 7, 8, 9, 11, 23, 24, 25, 26, 27, 28, 29}; +uint16_t table_7_3_1_1_2_3A[16] = {0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 14, 15}; +uint16_t table_7_3_1_1_2_4_1layer_fullyAndPartialAndNonCoherent[6] = {0, 1, 3, 4, 5, 6}; +uint16_t table_7_3_1_1_2_4_2layers_fullyAndPartialAndNonCoherent[3] = {2, 7, 8}; +uint16_t table_7_3_1_1_2_4A_1layer[3] = {0, 1, 3}; uint16_t table_7_3_1_1_2_28[3][15] = { {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -2760,6 +2774,250 @@ uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, return nbits; } +uint8_t compute_precoding_information(NR_PUSCH_Config_t *pusch_Config, + NR_SRS_Config_t *srs_config, + dci_field_t srs_resource_indicator, + nr_srs_feedback_t *srs_feedback, + const uint8_t *nrOfLayers, + uint16_t *val) { + + // It is only applicable to codebook based transmission. This field occupies 0 bits for non-codebook based + // transmission. It also occupies 0 bits for codebook based transmission using a single antenna port. + uint8_t nbits = 0; + if (val) { + *val = 0; + } + + uint8_t pusch_antenna_ports = get_pusch_nb_antenna_ports(pusch_Config, srs_config, srs_resource_indicator); + if ((pusch_Config && pusch_Config->txConfig != NULL && *pusch_Config->txConfig == NR_PUSCH_Config__txConfig_nonCodebook) || + pusch_antenna_ports == 1) { + return nbits; + } + + long max_rank = *pusch_Config->maxRank; + long *ul_FullPowerTransmission = pusch_Config->ext1 ? pusch_Config->ext1->ul_FullPowerTransmission_r16 : NULL; + long *codebookSubset = pusch_Config->codebookSubset; + + if (pusch_antenna_ports == 2) { + + if (max_rank == 1) { + // - 1 or 3 bits according to Table 7.3.1.1.2-5 for 2 antenna ports, if txConfig = codebook, ul-FullPowerTransmission + // is not configured or configured to fullpowerMode2 or configured to fullpower, and according to whether transform + // precoder is enabled or disabled, and the values of higher layer parameters maxRank and codebookSubset; + // - 2 bits according to Table 7.3.1.1.2-5A for 2 antenna ports, if txConfig = codebook, ul-FullPowerTransmission = + // fullpowerMode1, maxRank=1, and according to whether transform precoder is enabled or disabled, and the values + // of higher layer parameter codebookSubset; + if (ul_FullPowerTransmission && *ul_FullPowerTransmission == NR_PUSCH_Config__ext1__ul_FullPowerTransmission_r16_fullpowerMode1) { + nbits = 2; + if (val && srs_feedback) { + AssertFatal(srs_feedback->tpmi <= 2,"TPMI %d is invalid!\n", srs_feedback->tpmi); + *val = srs_feedback->tpmi; + } + } else { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + nbits = 1; + if (val && srs_feedback) { + AssertFatal(srs_feedback->tpmi <= 1,"TPMI %d is invalid!\n", srs_feedback->tpmi); + *val = srs_feedback->tpmi; + } + } else { + nbits = 3; + if (val && srs_feedback) { + AssertFatal(srs_feedback->tpmi <= 5,"TPMI %d is invalid!\n", srs_feedback->tpmi); + *val = srs_feedback->tpmi; + } + } + } + } else { + // - 2 or 4 bits according to Table 7.3.1.1.2-4 for 2 antenna ports, if txConfig = codebook, ul-FullPowerTransmission + // is not configured or configured to fullpowerMode2 or configured to fullpower, and according to whether transform + // precoder is enabled or disabled, and the values of higher layer parameters maxRank and codebookSubset; + // - 2 bits according to Table 7.3.1.1.2-4A for 2 antenna ports, if txConfig = codebook, ul-FullPowerTransmission = + // fullpowerMode1, transform precoder is disabled, maxRank=2, and codebookSubset=nonCoherent; + if (ul_FullPowerTransmission && *ul_FullPowerTransmission == NR_PUSCH_Config__ext1__ul_FullPowerTransmission_r16_fullpowerMode1) { + nbits = 2; + if (val && srs_feedback) { + AssertFatal((*nrOfLayers==1 && srs_feedback->tpmi <= 2) || (*nrOfLayers==2 && srs_feedback->tpmi == 0), + "TPMI %d is invalid!\n", srs_feedback->tpmi); + *val = *nrOfLayers==1 ? table_7_3_1_1_2_4A_1layer[srs_feedback->tpmi] : 2; + } + } else { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + nbits = 2; + if (val && srs_feedback) { + AssertFatal((*nrOfLayers==1 && srs_feedback->tpmi <= 1) || (*nrOfLayers==2 && srs_feedback->tpmi == 0), + "TPMI %d is invalid!\n", srs_feedback->tpmi); + *val = *nrOfLayers==1 ? srs_feedback->tpmi : 2; + } + } else { + nbits = 4; + if (val && srs_feedback) { + AssertFatal((*nrOfLayers==1 && srs_feedback->tpmi <= 5) || (*nrOfLayers==2 && srs_feedback->tpmi <= 2), + "TPMI %d is invalid!\n", srs_feedback->tpmi); + *val = *nrOfLayers==1 ? table_7_3_1_1_2_4_1layer_fullyAndPartialAndNonCoherent[srs_feedback->tpmi] : + table_7_3_1_1_2_4_2layers_fullyAndPartialAndNonCoherent[srs_feedback->tpmi]; + } + } + } + } + + } else if (pusch_antenna_ports == 4) { + + if (max_rank == 1) { + // - 2, 4, or 5 bits according to Table 7.3.1.1.2-3 for 4 antenna ports, if txConfig = codebook, ul-FullPowerTransmission + // is not configured or configured to fullpowerMode2 or configured to fullpower, and according to whether transform + // precoder is enabled or disabled, and the values of higher layer parameters maxRank, and codebookSubset; + // - 3 or 4 bits according to Table 7.3.1.1.2-3A for 4 antenna ports, if txConfig = codebook, ul-FullPowerTransmission = + // fullpowerMode1, maxRank=1, and according to whether transform precoder is enabled or disabled, and the values + // of higher layer parameter codebookSubset; + if (ul_FullPowerTransmission && *ul_FullPowerTransmission == NR_PUSCH_Config__ext1__ul_FullPowerTransmission_r16_fullpowerMode1) { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + nbits = 3; + if (val && srs_feedback) { + AssertFatal(srs_feedback->tpmi <= 3 || srs_feedback->tpmi == 13, "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } else { + nbits = 4; + if (val && srs_feedback) { + AssertFatal(srs_feedback->tpmi <= 15, "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } + if (val && srs_feedback) { + *val = table_7_3_1_1_2_3A[srs_feedback->tpmi]; + } + } else { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + nbits = 2; + if (val && srs_feedback) { + AssertFatal(srs_feedback->tpmi <= 3, "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } else if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent) { + nbits = 4; + if (val && srs_feedback) { + AssertFatal(srs_feedback->tpmi <= 11, "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } else { + nbits = 5; + if (val && srs_feedback) { + AssertFatal(srs_feedback->tpmi <= 27, "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } + if (val && srs_feedback) { + *val = srs_feedback->tpmi; + } + } + } else { + // - 4, 5, or 6 bits according to Table 7.3.1.1.2-2 for 4 antenna ports, if txConfig = codebook, ul-FullPowerTransmission + // is not configured or configured to fullpowerMode2 or configured to fullpower, and according to whether transform + // precoder is enabled or disabled, and the values of higher layer parameters maxRank, and codebookSubset; + // - 4 or 5 bits according to Table 7.3.1.1.2-2A for 4 antenna ports, if txConfig = codebook, ul-FullPowerTransmission = + // fullpowerMode1, maxRank=2, transform precoder is disabled, and according to the values of higher layer parameter + // codebookSubset; + // - 4 or 6 bits according to Table 7.3.1.1.2-2B for 4 antenna ports, if txConfig = codebook, ul-FullPowerTransmission = + // fullpowerMode1, maxRank=3 or 4, transform precoder is disabled, and according to the values of higher layer + // parameter codebookSubset; + if (ul_FullPowerTransmission && *ul_FullPowerTransmission == NR_PUSCH_Config__ext1__ul_FullPowerTransmission_r16_fullpowerMode1) { + if (max_rank == 2) { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + nbits = 4; + if (val && srs_feedback) { + AssertFatal((*nrOfLayers==1 && (srs_feedback->tpmi <= 3 || srs_feedback->tpmi==13)) || (*nrOfLayers==2 && srs_feedback->tpmi <= 6), + "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } else { + nbits = 5; + if (val && srs_feedback) { + AssertFatal((*nrOfLayers==1 && srs_feedback->tpmi <= 15) || (*nrOfLayers==2 && srs_feedback->tpmi <= 13), + "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } + if (val && srs_feedback) { + *val = *nrOfLayers==1 ? table_7_3_1_1_2_2A_1layer[srs_feedback->tpmi] : table_7_3_1_1_2_2A_2layers[srs_feedback->tpmi]; + } + } else { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + nbits = 4; + if (val && srs_feedback) { + AssertFatal((*nrOfLayers==1 && (srs_feedback->tpmi <= 3 || srs_feedback->tpmi == 13)) || (*nrOfLayers==2 && srs_feedback->tpmi <= 6) || + (*nrOfLayers==3 && srs_feedback->tpmi <= 1) || (*nrOfLayers==4 && srs_feedback->tpmi == 0), + "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } else { + nbits = 6; + if (val && srs_feedback) { + AssertFatal((*nrOfLayers==1 && srs_feedback->tpmi <= 15) || (*nrOfLayers==2 && srs_feedback->tpmi <= 13) || + (*nrOfLayers==3 && srs_feedback->tpmi <= 2) || (*nrOfLayers==4 && srs_feedback->tpmi <= 2), + "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } + if (val && srs_feedback) { + switch (*nrOfLayers) { + case 1: + *val = table_7_3_1_1_2_2B_1layer[srs_feedback->tpmi]; + break; + case 2: + *val = table_7_3_1_1_2_2B_2layers[srs_feedback->tpmi]; + break; + case 3: + *val = table_7_3_1_1_2_2B_3layers[srs_feedback->tpmi]; + break; + case 4: + *val = table_7_3_1_1_2_2B_4layers[srs_feedback->tpmi]; + break; + default: + LOG_E(NR_MAC,"Number of layers %d is invalid!\n", *nrOfLayers); + } + } + } + } else { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + nbits = 4; + if (val && srs_feedback) { + AssertFatal((*nrOfLayers==1 && srs_feedback->tpmi <= 3) || (*nrOfLayers==2 && srs_feedback->tpmi <= 5) || + (*nrOfLayers==3 && srs_feedback->tpmi == 0) || (*nrOfLayers==4 && srs_feedback->tpmi == 0), + "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } else if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent) { + nbits = 5; + if (val && srs_feedback) { + AssertFatal((*nrOfLayers==1 && srs_feedback->tpmi <= 11) || (*nrOfLayers==2 && srs_feedback->tpmi <= 13) || + (*nrOfLayers==3 && srs_feedback->tpmi <= 2) || (*nrOfLayers==4 && srs_feedback->tpmi <= 2), + "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } else { + nbits = 6; + if (val && srs_feedback) { + AssertFatal((*nrOfLayers==1 && srs_feedback->tpmi <= 28) || (*nrOfLayers==2 && srs_feedback->tpmi <= 22) || + (*nrOfLayers==3 && srs_feedback->tpmi <= 7) || (*nrOfLayers==4 && srs_feedback->tpmi <= 5), + "TPMI %d is invalid!\n", srs_feedback->tpmi); + } + } + if (val && srs_feedback) { + switch (*nrOfLayers) { + case 1: + *val = table_7_3_1_1_2_2_1layer[srs_feedback->tpmi]; + break; + case 2: + *val = table_7_3_1_1_2_2_2layers[srs_feedback->tpmi]; + break; + case 3: + *val = table_7_3_1_1_2_2_3layers[srs_feedback->tpmi]; + break; + case 4: + *val = table_7_3_1_1_2_2_4layers[srs_feedback->tpmi]; + break; + default: + LOG_E(NR_MAC,"Number of layers %d is invalid!\n", *nrOfLayers); + } + } + } + } + + } + + return nbits; +} + uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, const NR_BWP_UplinkCommon_t *initialUplinkBWP, const NR_CellGroupConfig_t *cg, @@ -2908,35 +3166,11 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, size += dci_pdu->srs_resource_indicator.nbits; LOG_D(NR_MAC,"dci_pdu->srs_resource_indicator.nbits %d\n", dci_pdu->srs_resource_indicator.nbits); // Precoding info and number of layers - long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwpd, (uint8_t*)&format, rnti_type, 0); - uint8_t pusch_antenna_ports = get_pusch_nb_antenna_ports(pusch_Config, srs_config, dci_pdu->srs_resource_indicator); - dci_pdu->precoding_information.nbits=0; - if (pusch_Config && pusch_Config->txConfig != NULL) { - if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook) { - if (pusch_antenna_ports > 1) { - if (pusch_antenna_ports == 4) { - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank>1)) - dci_pdu->precoding_information.nbits = 6-(*pusch_Config->codebookSubset); - else { - if(*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) - dci_pdu->precoding_information.nbits = 2; - else - dci_pdu->precoding_information.nbits = 5-(*pusch_Config->codebookSubset); - } - } - else { - AssertFatal(pusch_antenna_ports==2,"Not valid number of antenna ports"); - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank==2)) - dci_pdu->precoding_information.nbits = 4-(*pusch_Config->codebookSubset); - else - dci_pdu->precoding_information.nbits = 3-(*pusch_Config->codebookSubset); - } - } - } - } + dci_pdu->precoding_information.nbits = compute_precoding_information(pusch_Config, srs_config, dci_pdu->srs_resource_indicator, NULL, NULL, NULL); size += dci_pdu->precoding_information.nbits; LOG_D(NR_MAC,"dci_pdu->precoding_informaiton.nbits=%d\n",dci_pdu->precoding_information.nbits); // Antenna ports + long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwpd, (uint8_t*)&format, rnti_type, 0); NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = NULL; int xa=0; int xb=0; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index c251c8c59b..99fa5ec1cc 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -53,6 +53,13 @@ uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, nr_srs_feedback_t *srs_feedback, uint16_t *val); +uint8_t compute_precoding_information(NR_PUSCH_Config_t *pusch_Config, + NR_SRS_Config_t *srs_config, + dci_field_t srs_resource_indicator, + nr_srs_feedback_t *srs_feedback, + const uint8_t *nrOfLayers, + uint16_t *val); + uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDLBWP, const NR_BWP_UplinkCommon_t *initialULBWP, const NR_CellGroupConfig_t *cg, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index fc5e374ebf..78e6fe0cb0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1080,16 +1080,17 @@ void config_uldci(const NR_SIB1_t *sib1, uplinkConfig = cg->spCellConfig->spCellConfigDedicated->uplinkConfig; } compute_srs_resource_indicator(uplinkConfig, - ubwpd->pusch_Config ? ubwpd->pusch_Config->choice.setup : NULL, - ubwpd2 && ubwpd2->srs_Config ? ubwpd->srs_Config->choice.setup : NULL, + ubwpd2->pusch_Config ? ubwpd2->pusch_Config->choice.setup : NULL, + ubwpd2 && ubwpd2->srs_Config ? ubwpd2->srs_Config->choice.setup : NULL, srs_feedback, &dci_pdu_rel15->srs_resource_indicator.val); } - dci_pdu_rel15->precoding_information.val= 0; - if (pusch_pdu->nrOfLayers == 2) - dci_pdu_rel15->precoding_information.val = 4; - else if (pusch_pdu->nrOfLayers == 4) - dci_pdu_rel15->precoding_information.val = 11; + compute_precoding_information(ubwpd2->pusch_Config ? ubwpd2->pusch_Config->choice.setup : NULL, + ubwpd2 && ubwpd2->srs_Config ? ubwpd2->srs_Config->choice.setup : NULL, + dci_pdu_rel15->srs_resource_indicator, + srs_feedback, + &pusch_pdu->nrOfLayers, + &dci_pdu_rel15->precoding_information.val); // antenna_ports.val = 0 for transform precoder is disabled, dmrs-Type=1, maxLength=1, Rank=1/2/3/4 // Antenna Ports From 8759eae05e2f02827ac218ed7fb078a5b977fde6 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 31 May 2022 17:44:18 +0100 Subject: [PATCH 06/30] Fix in get_pusch_nb_antenna_ports --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index da38543f14..b51bddfe21 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2639,11 +2639,12 @@ uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config, n_antenna_port = *pusch_Config->maxRank; } else { - if(srs_config != NULL && srs_resource_indicator.nbits > 0) { + uint8_t sri = srs_resource_indicator.nbits > 0 ? srs_resource_indicator.val : 0; + if(srs_config != NULL) { for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) { NR_SRS_ResourceSet_t *srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; if(srs_resource_set->usage == NR_SRS_ResourceSet__usage_codebook) { - NR_SRS_Resource_t *srs_resource = srs_config->srs_ResourceToAddModList->list.array[srs_resource_indicator.val]; + NR_SRS_Resource_t *srs_resource = srs_config->srs_ResourceToAddModList->list.array[sri]; AssertFatal(srs_resource != NULL,"SRS resource indicated by DCI does not exist\n"); n_antenna_port = 1<nrofSRS_Ports; } From 17ed513a6049b7c6962d1b973c0871d10198f54a Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Wed, 1 Jun 2022 19:09:22 +0100 Subject: [PATCH 07/30] Fix after merge --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 6d3e23168f..963695245c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -812,7 +812,7 @@ void handle_nr_srs_measurements(const module_id_t module_id, } // TODO: This should be improved - NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + 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.tpmi = 0; From 319bef7c8767a15adf913193a9e8662dcb5703b8 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 2 Jun 2022 19:28:48 +0100 Subject: [PATCH 08/30] Use UE capability to select the the number of SRS ports --- openair2/RRC/NR/nr_rrc_config.c | 43 ++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 8b4af5d7c5..c54a65f03f 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -357,26 +357,29 @@ void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, NR_SRS_Resource_t *srs_res0=calloc(1,sizeof(*srs_res0)); srs_res0->srs_ResourceId = 0; srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1; - // if (uecap && - // uecap->featureSets && - // uecap->featureSets->featureSetsUplink && - // uecap->featureSets->featureSetsUplink->list.count > 0) { - // NR_FeatureSetUplink_t *ul_feature_setup = uecap->featureSets->featureSetsUplink->list.array[0]; - // switch (ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource) { - // case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n1: - // srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1; - // break; - // case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n2: - // srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports2; - // break; - // case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n4: - // srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports4; - // break; - // default: - // LOG_E(NR_RRC, "Max Number of SRS Ports Per Resource %ld is invalid!\n", - // ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource); - // } - // } + if (do_srs) { + if (uecap && + uecap->featureSets && + uecap->featureSets->featureSetsUplink && + uecap->featureSets->featureSetsUplink->list.count > 0) { + NR_FeatureSetUplink_t *ul_feature_setup = uecap->featureSets->featureSetsUplink->list.array[0]; + switch (ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource) { + case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n1: + srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1; + break; + case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n2: + srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports2; + break; + case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n4: + srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports4; + break; + default: + LOG_E(NR_RRC, "Max Number of SRS Ports Per Resource %ld is invalid!\n", + ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource); + } + } + LOG_I(NR_RRC, "SRS configured with %d ports\n", 1<nrofSRS_Ports); + } srs_res0->ptrs_PortIndex = NULL; srs_res0->transmissionComb.present = NR_SRS_Resource__transmissionComb_PR_n2; srs_res0->transmissionComb.choice.n2 = calloc(1,sizeof(*srs_res0->transmissionComb.choice.n2)); From 0a496f44c48107dfe0d393539f06bea5445671a1 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 2 Jun 2022 19:41:53 +0100 Subject: [PATCH 09/30] Add comment about 3GPP TS 38.133 - Section 8 - Table 8.2.1.2.7-2 --- openair2/RRC/NR/nr_rrc_defs.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 0d859ab6ff..683ed4b975 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -101,6 +101,12 @@ typedef struct nr_uid_linear_allocator_s { #define NR_RRC_RECONFIGURATION_DELAY_MS 10 #define NR_RRC_BWP_SWITCHING_DELAY_MS 6 +// 3GPP TS 38.133 - Section 8 - Table 8.2.1.2.7-2: Parameters which cause interruption other than SCS +// This table was recently added to 3GPP. It shows that changing the parameters locationAndBandwidth, nrofSRS-Ports or +// maxMIMO-Layers-r16 causes an interruption. This parameter is not yet being used in code, but has been placed here +// for future reference. +#define NR_OF_SRS_PORTS_SWITCHING_DELAY_MS 30 + #define NR_UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! #define NR_UE_INDEX_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1 From fa94c338a87e5dee47ee5081821ff24356cf8fc2 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Wed, 8 Jun 2022 11:37:03 +0100 Subject: [PATCH 10/30] Updates in FAPI so in the future to be able to have a TPMI on MAC at gNB based on SRS --- .../nfapi/public_inc/nfapi_interface.h | 19 ++ .../nfapi/public_inc/nfapi_nr_interface_scf.h | 99 ++++++-- nfapi/open-nFAPI/nfapi/src/nfapi_p7.c | 240 +++++++++++++----- openair1/PHY/defs_common.h | 1 + openair1/SCHED_NR/phy_procedures_nr_gNB.c | 92 ++++--- .../LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c | 19 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 55 ++-- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 7 +- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 7 +- 9 files changed, 384 insertions(+), 155 deletions(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index e1cfc26336..a7943bb9e5 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h @@ -4060,4 +4060,23 @@ 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_beamforming_report_t to a buffer + * + * \param pMessageBuf A pointer to a nfapi_nr_srs_beamforming_report_t structure + * \param pPackedBuf A pointer to the buffer that the nfapi_nr_srs_beamforming_report_t will be packed into + * \param packedBufLen The size of the buffer + * \return number of bytes written to the buffer + */ +int pack_nr_srs_beamforming_report(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen); + +/*! \brief Decodes a nfapi_nr_srs_beamforming_report_t from a buffer + * + * \param pMessageBuf A pointer to an encoded nfapi_nr_srs_beamforming_report_t + * \param messageBufLen The size of the encoded nfapi_nr_srs_beamforming_report_t + * \param pUnpackedBuf A pointer to the nfapi_nr_srs_beamforming_report_t + * \param unpackedBufLen The size of nfapi_nr_srs_beamforming_report_t structure. + * \return 0 means success, -1 means failure. + */ +int unpack_nr_srs_beamforming_report(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen); + #endif /* _NFAPI_INTERFACE_H_ */ diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index d228132981..d2f70b01c3 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -1114,17 +1114,15 @@ typedef struct { typedef struct { nfapi_nr_dig_bf_interface_t* dig_bf_interface_list; - } nfapi_nr_ul_beamforming_number_of_prgs_t; typedef struct { - uint16_t num_prgs; - uint16_t prg_size; - //watchout: dig_bf_interface here, in table 3-43 it's dig_bf_interfaces - uint8_t dig_bf_interface; - nfapi_nr_ul_beamforming_number_of_prgs_t* prgs_list;// - + uint8_t trp_scheme; // This field shall be set to 0, to identify that this table is used. + uint16_t num_prgs; // Number of PRGs spanning this allocation. Value : 1->275 + uint16_t prg_size; // Size in RBs of a precoding resource block group (PRG) – to which the same digital beamforming gets applied. Value: 1->275 + uint8_t dig_bf_interface; // Number of logical antenna ports (parallel streams) resulting from the Rx combining. Value: 0->255 + nfapi_nr_ul_beamforming_number_of_prgs_t *prgs_list; } nfapi_nr_ul_beamforming_t; typedef struct @@ -1298,6 +1296,28 @@ typedef struct } nfapi_nr_pucch_pdu_t; +typedef struct { + uint16_t srs_bandwidth_start; // PRB index for the start of SRS signal transmission. The PRB index is relative to the CRB0 or reference Point A. 3GPP TS 38.211, section 6.4.1.4.3. Value: 0->268 + uint8_t sequence_group; // Sequence group (u) as defined in 3GPP TS 38.211, section 6.4.1.4.2. Value: 0->29 + uint8_t sequence_number; // Sequence number (v) as defined in 3GPP TS 38.211, section 6.4.1.4.2 TS 38.211. Value: 0->1 +} nfapi_v4_srs_parameters_symbols_t; + +typedef struct { + uint16_t srs_bandwidth_size; // mSRS,b: Number of PRB’s that are sounded for each SRS symbol, per 3GPP TS 38.211, section 6.4.1.4.3. Value: 4->272 + nfapi_v4_srs_parameters_symbols_t *symbol_list; + uint32_t usage; // Bitmap indicating the type of report(s) expected at L2 from the SRS signaled by this PDU. Bit positions: 0 – beamManagement; 1 – codebook; 2 – nonCodebook; 3 – antennaSwitching; 4 – 255: reserved. For each of this bit positions: 1 = requested; 0 = not requested. nUsage = sum(all bits in usage) + uint8_t report_type[4]; // Interpretation of each Report Type depends on usage: beamManagement (1 = PRG SNR, 2-255 reserved); codebook (1 = PRG I and Q channel estimate, per srs Tx port and gNB antenna element, 2-255 reserved); nonCodebook (1 = PRG I and Q channel estimate, per SRI and gNB antenna element, 2-255 reserved); antennaSwitching (1 = SVD representation UE Rx and gNB sets of antenna element, 2-255 reserved); all (0 – no report required). + uint8_t singular_Value_representation; // 0 – 8-bit dB; 1 – 16-bit linear; 255 – not applicable + uint8_t iq_representation; // 0 – 16 bit; 1 – 32-bit; 255 - not applicable + uint16_t prg_size; // 1-272; 0 – reserved + uint8_t num_total_ue_antennas; // 1 … 16 in this release. This is the total number of UE antennas for the usage. + uint32_t ue_antennas_in_this_srs_resource_set; // Bitmap of UE antenna indices for the SRS Resource set, to which the SRS Resource for this PDU corresponds. + uint32_t sampled_ue_antennas; // Bitmap of UE antenna indices sampled by the SRS waveform corresponding to this PDU’s SRS Resource. Codebook: corresponds to antenna ports in SRS Resources; non-overlapping indices; Non-codebook: corresponds to SRIs; Antennas-switch: indices of UE Rx antennas in the total number of antennas. + uint8_t report_scope; // Which antennas Report (in ReportType) should account for: Value: 0: ports in sampledUeAntennas (i.e. SRS Resource); 1: ports in ueAntennasInSrsResourceSet (i.e. SRS Resource set. For antSwith reports of SVD type, value 0 is only allowed if sampledUeAntennas = ueAntennasInSrsResourceSet. + uint8_t num_ul_spatial_streams_ports; // In this release, L2 may set this number to 0 to leave spatial stream index assignment to L1 (e.g. L1 uses spatial streams reserved for SRS), regardless of the information in capability maxNumberUlSpatialStreams. + uint8_t Ul_spatial_stream_ports[256]; // Number of ports used for signaling this SRS allocation. Value: 0 --> (max # spatial streams - 1, per TLV) +} nfapi_v4_srs_parameters_t; + typedef struct { uint16_t rnti; // UE RNTI, Value: 1->65535 uint32_t handle; // An opaque handling returned in the SRS.indication @@ -1323,6 +1343,7 @@ typedef struct { uint16_t t_srs; // SRS-Periodicity in slots [3GPP TS 38.211, Sec 6.4.1.4.4], Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560 uint16_t t_offset; // Slot offset value [3GPP TS 38.211, Sec 6.4.1.4.3], Value:0->2559 nfapi_nr_ul_beamforming_t beamforming; + nfapi_v4_srs_parameters_t srs_parameters_v4; } nfapi_nr_srs_pdu_t; typedef enum { @@ -1666,33 +1687,63 @@ typedef struct } nfapi_nr_uci_indication_t; -/// 5G PHY FAPI Specification: SRS indication - Section 3.4.10, Table 3-73 +/// 5G PHY FAPI Specification: SRS indication - Section 3.4.10 + +// Normalized channel I/Q matrix typedef struct { - uint8_t rb_snr; // SNR value in dB. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB, 0xff will be set if this field is invalid. -} nfapi_nr_srs_indication_reported_symbol_resource_block_t; + uint8_t normalized_iq_representation; // 0: 16-bit normalized complex number (iqSize = 2); 1: 32-bit normalized complex number (iqSize = 4) + uint16_t num_gnb_antenna_elements; // Ng: Number of gNB antenna elements. Value: 0511 + uint16_t num_ue_srs_ports; // Nu: Number of sampled UE SRS ports. Value: 07 + uint16_t prg_size; // Size in RBs of a precoding resource block group (PRG) – to which the same digital beamforming gets applied. Value: 1->272 + uint16_t num_prgs; // Number of PRGs Np to be reported for this SRS PDU. Value: 0-> 272 + uint8_t channel_matrix[272*512*8*4]; // Array of (numPRGs*Nu*Ng) entries of the type denoted by iqRepresentation H{PRG pI} [ueAntenna uI, gNB antenna gI] = array[uI*Ng*Np + gI*Np + pI]; uI: 0…Nu-1 (UE antenna index); gI: 0…Ng-1 (gNB antenna index); pI: 0…Np-1 (PRG index) +} nfapi_nr_srs_normalized_channel_iq_matrix_t; + +// Beamforming report typedef struct { - uint16_t num_rbs; // Number of PRBs to be reported for this SRS PDU. Value: 0 -> 272. - nfapi_nr_srs_indication_reported_symbol_resource_block_t* rb_list; -} nfapi_nr_srs_indication_reported_symbol_t; + uint8_t rb_snr; // SNR value in dB. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB, 0xff will be set if this field is invalid. +} nfapi_nr_srs_reported_symbol_prgs_t; typedef struct { - uint32_t handle; // The handle passed to the PHY in the the UL_TTI.request SRS PDU. - uint16_t rnti; // The RNTI passed to the PHY in the UL_TTI.request SRS PDU. Value: 1 -> 65535. - uint16_t timing_advance; // Timing advance TA measured for the UE [TS 38.213, Section 4.2]. NTA_new = NTA_old + (TA − 31) * 16 * 64 / (2^u). Value: 0 -> 63. 0xffff should be set if this field is invalid. - uint8_t num_symbols; // Number of symbols for SRS. Value: 1 -> 4. If a PHY does not report for individual symbols then this parameter should be set to 1. - uint8_t wide_band_snr; // SNR value in dB measured within configured SRS bandwidth on each symbol. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB. 0xff will be set if this field is invalid. - uint8_t num_reported_symbols; // Number of symbols reported in this message. This allows PHY to report individual symbols or aggregated symbols where this field will be set to 1. Value: 1 -> 4. - nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list; + uint16_t num_prgs; // Number of PRBs to be reported for this SRS PDU. Value: 0 -> 272. + nfapi_nr_srs_reported_symbol_prgs_t *prg_list; +} nfapi_nr_srs_reported_symbol_t; + +typedef struct { + uint16_t prg_size; // Size in RBs of a precoding resource block group (PRG) – to which the same digital beamforming gets applied. Value: 1->275 + uint8_t num_symbols; // Number of symbols for SRS. Value: 1 -> 4. If a PHY does not report for individual symbols then this parameter should be set to 1. + uint8_t wide_band_snr; // SNR value in dB measured within configured SRS bandwidth on each symbol. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB. 0xff will be set if this field is invalid. + uint8_t num_reported_symbols; // Number of symbols reported in this message. This allows PHY to report individual symbols or aggregated symbols where this field will be set to 1. Value: 1 -> 4. + nfapi_nr_srs_reported_symbol_t *prgs; +} nfapi_nr_srs_beamforming_report_t; + +// SRS indication + +typedef struct { + uint16_t tag; // 0: Report is carried directly in the value field; 3: The offset from the end of the control portion of the message to the beginning of the report. Other values are reserved. + uint32_t length; // Length of the actual report in bytes, without the padding bytes. + uint32_t value[16384]; // tag=0: Only the most significant bytes of the size indicated by ‘length’ field are valid. Remaining bytes are zero padded to the nearest 32-bit bit boundary; Tag=2 Offset from the end of the control portion of the message to the payload is in the value field. Occupies 32-bits. +} nfapi_srs_report_tlv_t; + +typedef struct { + uint32_t handle; // The handle passed to the PHY in the the UL_TTI.request SRS PDU. + uint16_t rnti; // The RNTI passed to the PHY in the UL_TTI.request SRS PDU. Value: 1 -> 65535. + uint16_t timing_advance_offset; // Timing advance TA measured for the UE in multiples of 16 * 64 * Tc / (2^u) [TS 38.213, Section 4.2]. Value: 0 -> 63. 0xffff will be set if this field is invalid. + int16_t timing_advance_offset_nsec; // Timing advance measured for the UE between the reference uplink time and the observed arrival time for the UE. Value: -16800 … +16800 nanoseconds. 0xffff should be set if this field is invalid. + uint8_t srs_usage; // 0 – beamManagement; 1 – codebook; 2 – nonCodebook; 3 – antennaSwitching; 4 – 255: reserved; Note: This field matches the SRS usage field of the SRS PDU to which this report is linked. + uint8_t report_type; // The type of report included in or pointed to by Report TLV depends on the SRS usage: Beam management (1: Beamforming report); Codebook (1: Normalized Channel I/Q Matrix); nonCodebook (1: Normalized Channel I/Q Matrix); antennaSwitch (1: Channel SVD Representation); all (0: null report) + nfapi_srs_report_tlv_t *report_tlv; } nfapi_nr_srs_indication_pdu_t; typedef struct { nfapi_p7_message_header_t header; - uint16_t sfn; // SFN. Value: 0 -> 1023 - uint16_t slot; // Slot. Value: 0 -> 159 - uint8_t number_of_pdus; // Number of PDUs included in this message. Value: 0 -> 255 - nfapi_nr_srs_indication_pdu_t* pdu_list; + uint16_t sfn; // SFN. Value: 0 -> 1023 + uint16_t slot; // Slot. Value: 0 -> 159 + uint16_t control_length; // Size of control portion of SRS indication. 0 if reports are included inline; >0 if reports are concatenated to the end of the message. + uint8_t number_of_pdus; // Number of PDUs included in this message. Value: 0 -> 255 + nfapi_nr_srs_indication_pdu_t *pdu_list; } nfapi_nr_srs_indication_t; diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index 3adde23e7d..9bf723d10d 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -3101,42 +3101,99 @@ return 1; //SRS INDICATION -static uint8_t pack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - if(!(push32(value->handle, ppWritePackedMsg, end) && - push16(value->rnti, ppWritePackedMsg, end) && - push16(value->timing_advance, ppWritePackedMsg, end) && - push8(value->num_symbols, ppWritePackedMsg, end) && - push8(value->wide_band_snr, ppWritePackedMsg, end) && - push8(value->num_reported_symbols, ppWritePackedMsg, end) && - push8(value->reported_symbol_list->num_rbs, ppWritePackedMsg, end) - )) - return 0; - for(int i = 0; i < value->reported_symbol_list->num_rbs; i++) - { - if (!push8(value->reported_symbol_list->rb_list[i].rb_snr, ppWritePackedMsg, end)) - return 0; - } - return 1; +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)) { + return 0; + } + + for(int i = 0; i < prgs->num_prgs; i++) { + if (!push8(prgs->prg_list[i].rb_snr, ppWritePackedMsg, end)) { + return 0; + } + } + + return 1; } -static uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t*)msg; +int pack_nr_srs_beamforming_report(void *pMessageBuf, + void *pPackedBuf, + uint32_t packedBufLen) { - if (!(push16(pNfapiMsg->sfn , ppWritePackedMsg, end) && - push16(pNfapiMsg->slot , ppWritePackedMsg, end) && - push16(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end) - )) - return 0; + nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t*)pMessageBuf; - for(int i=0; inumber_of_pdus;i++) - { - if(!pack_nr_srs_indication_body(&(pNfapiMsg->pdu_list[i]),ppWritePackedMsg,end)) - return 0; - } + uint8_t *pWritePackedMessage = pPackedBuf; + uint8_t *end = pPackedBuf + packedBufLen; -return 1; + if(!(push16(nr_srs_beamforming_report->prg_size, &pWritePackedMessage, end) && + push8(nr_srs_beamforming_report->num_symbols, &pWritePackedMessage, end) && + push8(nr_srs_beamforming_report->wide_band_snr, &pWritePackedMessage, end) && + push8(nr_srs_beamforming_report->num_reported_symbols, &pWritePackedMessage, end))) { + return 0; + } + + if(!pack_nr_srs_reported_symbol(nr_srs_beamforming_report->prgs, &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_report_tlv(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { + + if(!(push16(report_tlv->tag, ppWritePackedMsg, end) && + push32(report_tlv->length, ppWritePackedMsg, end))) { + return 0; + } + + for(int i = 0; i < report_tlv->length; i++) { + if (!push32(report_tlv->value[i], ppWritePackedMsg, end)) { + return 0; + } + } + + return 1; +} + +static uint8_t pack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end) { + + if(!(push32(value->handle, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push16(value->timing_advance_offset, ppWritePackedMsg, end) && + pushs16(value->timing_advance_offset_nsec, ppWritePackedMsg, end) && + push8(value->srs_usage, ppWritePackedMsg, end) && + push8(value->report_type, ppWritePackedMsg, end))) { + return 0; + } + + if(!pack_nr_srs_report_tlv(value->report_tlv,ppWritePackedMsg, end)) { + return 0; + } + + return 1; +} + +static uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) { + + nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t*)msg; + + if (!(push16(pNfapiMsg->sfn , ppWritePackedMsg, end) && + push16(pNfapiMsg->slot , ppWritePackedMsg, end) && + push16(pNfapiMsg->control_length , ppWritePackedMsg, end) && + push8(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end))) { + return 0; + } + + for(int i=0; inumber_of_pdus;i++) { + if(!pack_nr_srs_indication_body(&(pNfapiMsg->pdu_list[i]),ppWritePackedMsg, end)) { + return 0; + } + } + + return 1; } //RACH INDICATION @@ -5797,40 +5854,101 @@ return 1; //SRS INDICATION -static uint8_t unpack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t* value, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - if(!(pull32(ppReadPackedMsg, &value->handle, end) && - pull16(ppReadPackedMsg, &value->rnti, end) && - pull16(ppReadPackedMsg, &value->timing_advance, end) && - pull8(ppReadPackedMsg, &value->num_symbols, end) && - pull8(ppReadPackedMsg, &value->wide_band_snr, end) && - pull8(ppReadPackedMsg, &value->num_reported_symbols, end) && - pull16(ppReadPackedMsg, &value->reported_symbol_list->num_rbs, end) - )) - return 0; - for(int i = 0; i < value->reported_symbol_list->num_rbs; i++) - { - if (!pull8(ppReadPackedMsg, &value->reported_symbol_list->rb_list[i].rb_snr, end)) - return 0; - } - return 1; +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)) { + return 0; + } + + if(!prgs->prg_list) { + prgs->prg_list = (nfapi_nr_srs_reported_symbol_prgs_t*) calloc(1, prgs->num_prgs*sizeof(nfapi_nr_srs_reported_symbol_prgs_t)); + } + + for(int i = 0; i < prgs->num_prgs; i++) { + if (!pull8(ppReadPackedMsg, &prgs->prg_list[i].rb_snr, end)) { + return 0; + } + } + + return 1; } -static uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_nr_srs_indication_t *pNfapiMsg, nfapi_p7_codec_config_t* config) -{ - if (!(pull16(ppReadPackedMsg,&pNfapiMsg->sfn , end) && - pull16(ppReadPackedMsg,&pNfapiMsg->slot , end) && - pull8(ppReadPackedMsg,&pNfapiMsg->number_of_pdus, end) - )) - return 0; +int unpack_nr_srs_beamforming_report(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen) { - for(int i=0; inumber_of_pdus;i++) - { - if (!unpack_nr_srs_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end)) - return 0; - } + nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t*)pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; -return 1; + memset(pUnpackedBuf, 0, unpackedBufLen); + + if(!(pull16(&pReadPackedMessage, &nr_srs_beamforming_report->prg_size, end) && + pull8(&pReadPackedMessage, &nr_srs_beamforming_report->num_symbols, end) && + pull8(&pReadPackedMessage, &nr_srs_beamforming_report->wide_band_snr, end) && + pull8(&pReadPackedMessage, &nr_srs_beamforming_report->num_reported_symbols, end))) { + return -1; + } + + if(!nr_srs_beamforming_report->prgs) { + nr_srs_beamforming_report->prgs = (nfapi_nr_srs_reported_symbol_t*) calloc(1, sizeof(nfapi_nr_srs_reported_symbol_t)); + } + + if(!unpack_nr_srs_reported_symbol(nr_srs_beamforming_report->prgs, &pReadPackedMessage, end)) { + return -1; + } + + return 0; +} + +static uint8_t unpack_nr_srs_report_tlv(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end) { + + if(!(pull16(ppReadPackedMsg, &report_tlv->tag, end) && + pull32(ppReadPackedMsg, &report_tlv->length, end))) { + return 0; + } + + for(int i = 0; i < report_tlv->length; i++) { + if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) { + return 0; + } + } + + return 1; +} + +static uint8_t unpack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppReadPackedMsg, uint8_t *end) { + + if(!(pull32(ppReadPackedMsg, &value->handle, end) && + pull16(ppReadPackedMsg, &value->rnti, end) && + pull16(ppReadPackedMsg, &value->timing_advance_offset, end) && + pulls16(ppReadPackedMsg, &value->timing_advance_offset_nsec, end) && + pull8(ppReadPackedMsg, &value->srs_usage, end) && + pull8(ppReadPackedMsg, &value->report_type, end))) { + return 0; + } + + if(!unpack_nr_srs_report_tlv(value->report_tlv, ppReadPackedMsg, end)) { + return 0; + } + + return 1; +} + +static uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_nr_srs_indication_t *pNfapiMsg, nfapi_p7_codec_config_t* config) { + + if (!(pull16(ppReadPackedMsg,&pNfapiMsg->sfn, end) && + pull16(ppReadPackedMsg,&pNfapiMsg->slot, end) && + pull16(ppReadPackedMsg,&pNfapiMsg->control_length, end) && + pull8(ppReadPackedMsg,&pNfapiMsg->number_of_pdus, end))) { + return 0; + } + + for(int i=0; inumber_of_pdus; i++) { + if (!unpack_nr_srs_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end)) { + return 0; + } + } + + return 1; } //NR RACH diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index d13fe260de..8313a52ce3 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -98,6 +98,7 @@ #define NB_RX_ANTENNAS_MAX 64 +#define TC_NSEC_x32768 16667 typedef enum {TDD=1,FDD=0} frame_type_t; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 64039e5239..3f9cff3d7f 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -633,27 +633,27 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } -int fill_srs_reported_symbol_list(nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list, +int fill_srs_reported_symbol_list(nfapi_nr_srs_reported_symbol_t *prgs, nfapi_nr_srs_pdu_t *srs_pdu, int N_RB_UL, const int8_t *snr_per_rb, int srs_est) { - reported_symbol_list->num_rbs = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0]; + prgs->num_prgs = srs_pdu->beamforming.num_prgs; - if (!reported_symbol_list->rb_list) { - reported_symbol_list->rb_list = (nfapi_nr_srs_indication_reported_symbol_resource_block_t*) calloc(1, N_RB_UL*sizeof(nfapi_nr_srs_indication_reported_symbol_resource_block_t)); + if (!prgs->prg_list) { + prgs->prg_list = (nfapi_nr_srs_reported_symbol_prgs_t*) calloc(1, N_RB_UL*sizeof(nfapi_nr_srs_reported_symbol_prgs_t)); } - for(int rb = 0; rb < reported_symbol_list->num_rbs; rb++) { + for(int prg_idx = 0; prg_idx < prgs->num_prgs; prg_idx++) { if (srs_est<0) { - reported_symbol_list->rb_list[rb].rb_snr = 0xFF; - } else if (snr_per_rb[rb] < -64) { - reported_symbol_list->rb_list[rb].rb_snr = 0; - } else if (snr_per_rb[rb] > 63) { - reported_symbol_list->rb_list[rb].rb_snr = 0xFE; + prgs->prg_list[prg_idx].rb_snr = 0xFF; + } else if (snr_per_rb[prg_idx] < -64) { + prgs->prg_list[prg_idx].rb_snr = 0; + } else if (snr_per_rb[prg_idx] > 63) { + prgs->prg_list[prg_idx].rb_snr = 0xFE; } else { - reported_symbol_list->rb_list[rb].rb_snr = (snr_per_rb[rb] + 64)<<1; + prgs->prg_list[prg_idx].rb_snr = (snr_per_rb[prg_idx] + 64) << 1; } } @@ -890,36 +890,64 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { gNB->UL_INFO.srs_ind.slot = slot_rx; gNB->srs_pdu_list[num_srs].handle = srs_pdu->handle; gNB->srs_pdu_list[num_srs].rnti = srs_pdu->rnti; - gNB->srs_pdu_list[num_srs].timing_advance = nr_est_timing_advance_srs(&gNB->frame_parms, gNB->nr_srs_info[i]->srs_estimated_channel_time[0]); - gNB->srs_pdu_list[num_srs].num_symbols = 1<num_symbols; - gNB->srs_pdu_list[num_srs].wide_band_snr = srs_est >= 0 ? (*gNB->nr_srs_info[i]->snr + 64)<<1 : 0xFF; // 0xFF will be set if this field is invalid - gNB->srs_pdu_list[num_srs].num_reported_symbols = 1<num_symbols; - if(!gNB->srs_pdu_list[num_srs].reported_symbol_list) { - gNB->srs_pdu_list[num_srs].reported_symbol_list = (nfapi_nr_srs_indication_reported_symbol_t*) calloc(1, gNB->srs_pdu_list[num_srs].num_reported_symbols*sizeof(nfapi_nr_srs_indication_reported_symbol_t)); - } - fill_srs_reported_symbol_list(&gNB->srs_pdu_list[num_srs].reported_symbol_list[0], + 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; + +#ifdef SRS_IND_DEBUG + LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.sfn = %i\n", gNB->UL_INFO.srs_ind.sfn); + LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.slot = %i\n", gNB->UL_INFO.srs_ind.slot); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].rnti = %04x\n", num_srs, gNB->srs_pdu_list[num_srs].rnti); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].timing_advance = %i\n", num_srs, gNB->srs_pdu_list[num_srs].timing_advance_offset); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].timing_advance_offset_nsec = %i\n", num_srs, gNB->srs_pdu_list[num_srs].timing_advance_offset_nsec); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].srs_usage = %i\n", num_srs, gNB->srs_pdu_list[num_srs].srs_usage); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].report_type = %i\n", num_srs, gNB->srs_pdu_list[num_srs].report_type); +#endif + + 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<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 + nr_srs_beamforming_report->num_reported_symbols = 1<num_symbols; + nr_srs_beamforming_report->prgs = (nfapi_nr_srs_reported_symbol_t*) calloc(1, nr_srs_beamforming_report->num_reported_symbols*sizeof(nfapi_nr_srs_reported_symbol_t)); + fill_srs_reported_symbol_list(&nr_srs_beamforming_report->prgs[0], srs_pdu, gNB->frame_parms.N_RB_UL, gNB->nr_srs_info[i]->snr_per_rb, srs_est); - gNB->UL_INFO.srs_ind.number_of_pdus += 1; - #ifdef SRS_IND_DEBUG - LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.sfn = %i\n", gNB->UL_INFO.srs_ind.sfn); - LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.slot = %i\n", gNB->UL_INFO.srs_ind.slot); - LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].rnti = 0x%04x\n", num_srs, gNB->srs_pdu_list[num_srs].rnti); - LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].timing_advance = %i\n", num_srs, gNB->srs_pdu_list[num_srs].timing_advance); - LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].num_symbols = %i\n", num_srs, gNB->srs_pdu_list[num_srs].num_symbols); - LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].wide_band_snr = %i\n", num_srs, gNB->srs_pdu_list[num_srs].wide_band_snr); - LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].num_reported_symbols = %i\n", num_srs, gNB->srs_pdu_list[num_srs].num_reported_symbols); - LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].reported_symbol_list[0].num_rbs = %i\n", num_srs, gNB->srs_pdu_list[num_srs].reported_symbol_list[0].num_rbs); - for(int rb = 0; rb < gNB->srs_pdu_list[num_srs].reported_symbol_list[0].num_rbs; rb++) { - LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].reported_symbol_list[0].rb_list[%3i].rb_snr = %i\n", - num_srs, rb, gNB->srs_pdu_list[num_srs].reported_symbol_list[0].rb_list[rb].rb_snr); + LOG_I(NR_PHY, "nr_srs_beamforming_report->prg_size = %i\n", nr_srs_beamforming_report->prg_size); + LOG_I(NR_PHY, "nr_srs_beamforming_report->num_symbols = %i\n", nr_srs_beamforming_report->num_symbols); + LOG_I(NR_PHY, "nr_srs_beamforming_report->wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report->wide_band_snr, (nr_srs_beamforming_report->wide_band_snr>>1)-64); + LOG_I(NR_PHY, "nr_srs_beamforming_report->num_reported_symbols = %i\n", nr_srs_beamforming_report->num_reported_symbols); + LOG_I(NR_PHY, "nr_srs_beamforming_report->prgs[0].num_prgs = %i\n", nr_srs_beamforming_report->prgs[0].num_prgs); + for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report->prgs[0].num_prgs; prg_idx++) { + LOG_I(NR_PHY, "nr_srs_beamforming_report->prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n", + prg_idx, + nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr, + (nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr>>1)-64); } #endif + if(!gNB->srs_pdu_list[num_srs].report_tlv) { + 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 = pack_nr_srs_beamforming_report(nr_srs_beamforming_report, + gNB->srs_pdu_list[num_srs].report_tlv->value, + 16384*sizeof(uint32_t)); + +#ifdef SRS_IND_DEBUG + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].report_tlv->length = %i\n", num_srs, gNB->srs_pdu_list[num_srs].report_tlv->length); + char *value = (char*)gNB->srs_pdu_list[num_srs].report_tlv->value; + for(int b = 0; b < gNB->srs_pdu_list[num_srs].report_tlv->length; b++) { + LOG_I(NR_PHY, "value[%i] = 0x%02x\n", b, value[b]&0xFF); + } +#endif + + gNB->UL_INFO.srs_ind.number_of_pdus += 1; srs->active = 0; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index 7a21ad82e8..09c1dc17d3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -34,7 +34,12 @@ extern RAN_CONTEXT_t RC; -void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id,NR_UE_info_t* UE, NR_SRS_Resource_t *srs_resource) { +const uint16_t m_SRS[64] = { 4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 48, 52, 56, 60, 64, 72, 72, 76, 80, 88, + 96, 96, 104, 112, 120, 120, 120, 128, 128, 128, 132, 136, 144, 144, 144, 144, 152, 160, + 160, 160, 168, 176, 184, 192, 192, 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256, + 256, 264, 272, 272, 272 }; + +void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id,NR_UE_info_t* UE, NR_SRS_ResourceSet_t *srs_resource_set, NR_SRS_Resource_t *srs_resource) { gNB_MAC_INST *nrmac = RC.nrmac[module_id]; NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; @@ -80,9 +85,15 @@ void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id,NR_U srs_pdu->resource_type = srs_resource->resourceType.present - 1; srs_pdu->t_srs = srs_period[srs_resource->resourceType.choice.periodic->periodicityAndOffset_p.present]; 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; } -void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, sub_frame_t slot, NR_SRS_Resource_t *srs_resource) { +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) { nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][slot]; AssertFatal(future_ul_tti_req->n_pdus < @@ -94,7 +105,7 @@ void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, sub_frame_t s memset(srs_pdu, 0, sizeof(nfapi_nr_srs_pdu_t)); future_ul_tti_req->n_pdus += 1; - nr_configure_srs(srs_pdu, module_id, CC_id, UE, srs_resource); + nr_configure_srs(srs_pdu, module_id, CC_id, UE, srs_resource_set, srs_resource); } /******************************************************************* @@ -185,7 +196,7 @@ void nr_schedule_srs(int module_id, frame_t frame) { // Check if UE will transmit the SRS in this frame if ( ((frame - offset/n_slots_frame)*n_slots_frame)%period == 0) { LOG_D(NR_MAC,"Scheduling SRS reception for %d.%d\n", frame, offset%n_slots_frame); - nr_fill_nfapi_srs(module_id, CC_id, UE, offset%n_slots_frame, srs_resource); + nr_fill_nfapi_srs(module_id, CC_id, UE, offset%n_slots_frame, srs_resource_set, srs_resource); sched_ctrl->sched_srs.frame = frame; sched_ctrl->sched_srs.slot = offset%n_slots_frame; sched_ctrl->sched_srs.srs_scheduled = true; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 963695245c..c1d7f05d1a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -765,46 +765,57 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, void handle_nr_srs_measurements(const module_id_t module_id, const frame_t frame, const sub_frame_t slot, - const rnti_t rnti, - const uint16_t timing_advance, - const uint8_t num_symbols, - const uint8_t wide_band_snr, - const uint8_t num_reported_symbols, - nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list) { + const nfapi_nr_srs_indication_pdu_t *srs_ind) { - LOG_D(NR_MAC, "(%d.%d) Received SRS indication for rnti: 0x%04x\n", frame, slot, rnti); + LOG_D(NR_MAC, "(%d.%d) Received SRS indication for UE %04x\n", frame, slot, srs_ind->rnti); #ifdef SRS_IND_DEBUG LOG_I(NR_MAC, "frame = %i\n", frame); LOG_I(NR_MAC, "slot = %i\n", slot); - LOG_I(NR_MAC, "rnti = 0x%04x\n", rnti); - LOG_I(NR_MAC, "timing_advance = %i\n", timing_advance); - LOG_I(NR_MAC, "num_symbols = %i\n", num_symbols); - LOG_I(NR_MAC, "wide_band_snr = %i (%i dB)\n", wide_band_snr, (wide_band_snr>>1)-64); - LOG_I(NR_MAC, "num_reported_symbols = %i\n", num_reported_symbols); - LOG_I(NR_MAC, "reported_symbol_list[0].num_rbs = %i\n", reported_symbol_list[0].num_rbs); - for(int rb = 0; rb < reported_symbol_list[0].num_rbs; rb++) { - LOG_I(NR_MAC, "reported_symbol_list[0].rb_list[%3i].rb_snr = %i (%i dB)\n", - rb, reported_symbol_list[0].rb_list[rb].rb_snr, (reported_symbol_list[0].rb_list[rb].rb_snr>>1)-64); + LOG_I(NR_MAC, "srs_ind->rnti = %04x\n", srs_ind->rnti); + LOG_I(NR_MAC, "srs_ind->timing_advance_offset = %i\n", srs_ind->timing_advance_offset); + LOG_I(NR_MAC, "srs_ind->timing_advance_offset_nsec = %i\n", srs_ind->timing_advance_offset_nsec); + LOG_I(NR_MAC, "srs_ind->srs_usage = %i\n", srs_ind->srs_usage); + LOG_I(NR_MAC, "srs_ind->report_type = %i\n", srs_ind->report_type); +#endif + + 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, + sizeof(nfapi_nr_srs_beamforming_report_t)); + +#ifdef SRS_IND_DEBUG + LOG_I(NR_MAC, "nr_srs_beamforming_report->prg_size = %i\n", nr_srs_beamforming_report->prg_size); + LOG_I(NR_MAC, "nr_srs_beamforming_report->num_symbols = %i\n", nr_srs_beamforming_report->num_symbols); + LOG_I(NR_MAC, "nr_srs_beamforming_report->wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report->wide_band_snr, (nr_srs_beamforming_report->wide_band_snr>>1)-64); + LOG_I(NR_MAC, "nr_srs_beamforming_report->num_reported_symbols = %i\n", nr_srs_beamforming_report->num_reported_symbols); + LOG_I(NR_MAC, "nr_srs_beamforming_report->prgs[0].num_prgs = %i\n", nr_srs_beamforming_report->prgs[0].num_prgs); + for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report->prgs[0].num_prgs; prg_idx++) { + LOG_I(NR_MAC, "nr_srs_beamforming_report->prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n", + prg_idx, + nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr, + (nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr>>1)-64); } #endif - NR_UE_info_t* UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, rnti); + NR_UE_info_t* UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, srs_ind->rnti); if (!UE) { - LOG_W(NR_MAC, "Could not find UE for RNTI 0x%04x\n", rnti); + LOG_W(NR_MAC, "Could not find UE %04x\n", srs_ind->rnti); return; } gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; NR_mac_stats_t *stats = &UE->mac_stats; - stats->srs_wide_band_snr = (wide_band_snr>>1)-64; + stats->srs_wide_band_snr = (nr_srs_beamforming_report->wide_band_snr>>1)-64; int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold; uint16_t *ulprbbl = nr_mac->ulprbbl; - memset(ulprbbl, 0, reported_symbol_list[0].num_rbs*sizeof(uint16_t)); - for (int rb = 0; rb < reported_symbol_list[0].num_rbs; rb++) { - int snr = (reported_symbol_list[0].rb_list[rb].rb_snr>>1)-64; + uint8_t num_rbs = nr_srs_beamforming_report->prg_size * nr_srs_beamforming_report->prgs[0].num_prgs; + memset(ulprbbl, 0, num_rbs*sizeof(uint16_t)); + for (int rb = 0; rb < num_rbs; rb++) { + int snr = (nr_srs_beamforming_report->prgs[0].prg_list[rb/nr_srs_beamforming_report->prg_size].rb_snr>>1)-64; if (snr < ul_prbblack_SNR_threshold) { ulprbbl[rb] = 0x3FFF; // all symbols taken } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 835498d16f..75ec8e3207 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -493,12 +493,7 @@ void handle_nr_ul_harq(const int CC_idP, void handle_nr_srs_measurements(const module_id_t module_id, const frame_t frame, const sub_frame_t slot, - const rnti_t rnti, - const uint16_t timing_advance, - const uint8_t num_symbols, - const uint8_t wide_band_snr, - const uint8_t num_reported_symbols, - nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list); + const nfapi_nr_srs_indication_pdu_t *srs_ind); int16_t ssb_index_from_prach(module_id_t module_idP, frame_t frameP, diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 211b566c5a..06cf78b925 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -239,12 +239,7 @@ void handle_nr_srs(NR_UL_IND_t *UL_info) { handle_nr_srs_measurements(module_id, frame, slot, - srs_ind->rnti, - srs_ind->timing_advance, - srs_ind->num_symbols, - srs_ind->wide_band_snr, - srs_ind->num_reported_symbols, - srs_ind->reported_symbol_list); + &srs_list[i]); } UL_info->srs_ind.number_of_pdus = 0; From 51c95d2747f48d50df8a2770b52d3f8de1bdb89c Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Fri, 10 Jun 2022 14:27:56 +0100 Subject: [PATCH 11/30] Send correct FAPI SRS indication PDU depending on SRS usage --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 81 +++++++++------ .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 98 ++++++++++++------- 2 files changed, 112 insertions(+), 67 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 544437cfe3..b5bd6e68ec 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -905,41 +905,64 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].report_type = %i\n", num_srs, gNB->srs_pdu_list[num_srs].report_type); #endif - 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<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 - nr_srs_beamforming_report->num_reported_symbols = 1<num_symbols; - nr_srs_beamforming_report->prgs = (nfapi_nr_srs_reported_symbol_t*) calloc(1, nr_srs_beamforming_report->num_reported_symbols*sizeof(nfapi_nr_srs_reported_symbol_t)); - fill_srs_reported_symbol_list(&nr_srs_beamforming_report->prgs[0], - srs_pdu, - gNB->frame_parms.N_RB_UL, - gNB->nr_srs_info[i]->snr_per_rb, - srs_est); - -#ifdef SRS_IND_DEBUG - LOG_I(NR_PHY, "nr_srs_beamforming_report->prg_size = %i\n", nr_srs_beamforming_report->prg_size); - LOG_I(NR_PHY, "nr_srs_beamforming_report->num_symbols = %i\n", nr_srs_beamforming_report->num_symbols); - LOG_I(NR_PHY, "nr_srs_beamforming_report->wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report->wide_band_snr, (nr_srs_beamforming_report->wide_band_snr>>1)-64); - LOG_I(NR_PHY, "nr_srs_beamforming_report->num_reported_symbols = %i\n", nr_srs_beamforming_report->num_reported_symbols); - LOG_I(NR_PHY, "nr_srs_beamforming_report->prgs[0].num_prgs = %i\n", nr_srs_beamforming_report->prgs[0].num_prgs); - for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report->prgs[0].num_prgs; prg_idx++) { - LOG_I(NR_PHY, "nr_srs_beamforming_report->prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n", - prg_idx, - nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr, - (nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr>>1)-64); - } -#endif - if(!gNB->srs_pdu_list[num_srs].report_tlv) { 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 = pack_nr_srs_beamforming_report(nr_srs_beamforming_report, - gNB->srs_pdu_list[num_srs].report_tlv->value, - 16384*sizeof(uint32_t)); + + 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)); + nr_srs_beamforming_report->prg_size = srs_pdu->beamforming.prg_size; + nr_srs_beamforming_report->num_symbols = 1<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 + nr_srs_beamforming_report->num_reported_symbols = 1<num_symbols; + nr_srs_beamforming_report->prgs = (nfapi_nr_srs_reported_symbol_t*) calloc(1, nr_srs_beamforming_report->num_reported_symbols*sizeof(nfapi_nr_srs_reported_symbol_t)); + fill_srs_reported_symbol_list(&nr_srs_beamforming_report->prgs[0], + srs_pdu, + gNB->frame_parms.N_RB_UL, + gNB->nr_srs_info[i]->snr_per_rb, + srs_est); #ifdef SRS_IND_DEBUG + LOG_I(NR_PHY, "nr_srs_beamforming_report->prg_size = %i\n", nr_srs_beamforming_report->prg_size); + LOG_I(NR_PHY, "nr_srs_beamforming_report->num_symbols = %i\n", nr_srs_beamforming_report->num_symbols); + LOG_I(NR_PHY, "nr_srs_beamforming_report->wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report->wide_band_snr, (nr_srs_beamforming_report->wide_band_snr>>1)-64); + LOG_I(NR_PHY, "nr_srs_beamforming_report->num_reported_symbols = %i\n", nr_srs_beamforming_report->num_reported_symbols); + LOG_I(NR_PHY, "nr_srs_beamforming_report->prgs[0].num_prgs = %i\n", nr_srs_beamforming_report->prgs[0].num_prgs); + for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report->prgs[0].num_prgs; prg_idx++) { + LOG_I(NR_PHY, "nr_srs_beamforming_report->prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n", + prg_idx, + nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr, + (nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr>>1)-64); + } +#endif + + gNB->srs_pdu_list[num_srs].report_tlv->length = pack_nr_srs_beamforming_report(nr_srs_beamforming_report, + gNB->srs_pdu_list[num_srs].report_tlv->value, + 16384*sizeof(uint32_t)); + break; + } + + case NR_SRS_ResourceSet__usage_codebook: { + gNB->srs_pdu_list[num_srs].report_tlv->length = 0; + 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: + AssertFatal(1==0,"Invalid SRS usage\n"); + } + +#ifdef SRS_IND_DEBUG + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].report_tlv->tag = %i\n", num_srs, gNB->srs_pdu_list[num_srs].report_tlv->tag); LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].report_tlv->length = %i\n", num_srs, gNB->srs_pdu_list[num_srs].report_tlv->length); char *value = (char*)gNB->srs_pdu_list[num_srs].report_tlv->value; for(int b = 0; b < gNB->srs_pdu_list[num_srs].report_tlv->length; b++) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index cd1696f7bd..6bbc2c2750 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -779,54 +779,76 @@ void handle_nr_srs_measurements(const module_id_t module_id, LOG_I(NR_MAC, "srs_ind->report_type = %i\n", srs_ind->report_type); #endif - 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, - sizeof(nfapi_nr_srs_beamforming_report_t)); - -#ifdef SRS_IND_DEBUG - LOG_I(NR_MAC, "nr_srs_beamforming_report->prg_size = %i\n", nr_srs_beamforming_report->prg_size); - LOG_I(NR_MAC, "nr_srs_beamforming_report->num_symbols = %i\n", nr_srs_beamforming_report->num_symbols); - LOG_I(NR_MAC, "nr_srs_beamforming_report->wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report->wide_band_snr, (nr_srs_beamforming_report->wide_band_snr>>1)-64); - LOG_I(NR_MAC, "nr_srs_beamforming_report->num_reported_symbols = %i\n", nr_srs_beamforming_report->num_reported_symbols); - LOG_I(NR_MAC, "nr_srs_beamforming_report->prgs[0].num_prgs = %i\n", nr_srs_beamforming_report->prgs[0].num_prgs); - for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report->prgs[0].num_prgs; prg_idx++) { - LOG_I(NR_MAC, "nr_srs_beamforming_report->prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n", - prg_idx, - nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr, - (nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr>>1)-64); - } -#endif - - NR_UE_info_t* UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, srs_ind->rnti); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, srs_ind->rnti); if (!UE) { LOG_W(NR_MAC, "Could not find UE %04x\n", srs_ind->rnti); return; } - gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; - NR_mac_stats_t *stats = &UE->mac_stats; - stats->srs_wide_band_snr = (nr_srs_beamforming_report->wide_band_snr>>1)-64; + switch (srs_ind->srs_usage) { - int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold; - uint16_t *ulprbbl = nr_mac->ulprbbl; + case NR_SRS_ResourceSet__usage_beamManagement: { - uint8_t num_rbs = nr_srs_beamforming_report->prg_size * nr_srs_beamforming_report->prgs[0].num_prgs; - memset(ulprbbl, 0, num_rbs*sizeof(uint16_t)); - for (int rb = 0; rb < num_rbs; rb++) { - int snr = (nr_srs_beamforming_report->prgs[0].prg_list[rb/nr_srs_beamforming_report->prg_size].rb_snr>>1)-64; - if (snr < ul_prbblack_SNR_threshold) { - ulprbbl[rb] = 0x3FFF; // all symbols taken + 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, + sizeof(nfapi_nr_srs_beamforming_report_t)); + +#ifdef SRS_IND_DEBUG + LOG_I(NR_MAC, "nr_srs_beamforming_report->prg_size = %i\n", nr_srs_beamforming_report->prg_size); + LOG_I(NR_MAC, "nr_srs_beamforming_report->num_symbols = %i\n", nr_srs_beamforming_report->num_symbols); + LOG_I(NR_MAC, "nr_srs_beamforming_report->wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report->wide_band_snr, (nr_srs_beamforming_report->wide_band_snr>>1)-64); + LOG_I(NR_MAC, "nr_srs_beamforming_report->num_reported_symbols = %i\n", nr_srs_beamforming_report->num_reported_symbols); + LOG_I(NR_MAC, "nr_srs_beamforming_report->prgs[0].num_prgs = %i\n", nr_srs_beamforming_report->prgs[0].num_prgs); + for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report->prgs[0].num_prgs; prg_idx++) { + LOG_I(NR_MAC, "nr_srs_beamforming_report->prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n", + prg_idx, + nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr, + (nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr>>1)-64); + } +#endif + + gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; + NR_mac_stats_t *stats = &UE->mac_stats; + stats->srs_wide_band_snr = (nr_srs_beamforming_report->wide_band_snr>>1)-64; + + int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold; + uint16_t *ulprbbl = nr_mac->ulprbbl; + + uint8_t num_rbs = nr_srs_beamforming_report->prg_size * nr_srs_beamforming_report->prgs[0].num_prgs; + memset(ulprbbl, 0, num_rbs*sizeof(uint16_t)); + for (int rb = 0; rb < num_rbs; rb++) { + int snr = (nr_srs_beamforming_report->prgs[0].prg_list[rb/nr_srs_beamforming_report->prg_size].rb_snr>>1)-64; + if (snr < ul_prbblack_SNR_threshold) { + ulprbbl[rb] = 0x3FFF; // all symbols taken + } + LOG_D(NR_MAC, "ulprbbl[%3i] = 0x%x\n", rb, ulprbbl[rb]); + } + + break; } - LOG_D(NR_MAC, "ulprbbl[%3i] = 0x%x\n", rb, ulprbbl[rb]); + + case NR_SRS_ResourceSet__usage_codebook: { + + // 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.tpmi = 0; + + break; + } + + case NR_SRS_ResourceSet__usage_nonCodebook: + case NR_SRS_ResourceSet__usage_antennaSwitching: + LOG_W(NR_MAC, "MAC procedures for this SRS usage are not implemented yet!\n"); + break; + + default: + AssertFatal(1==0,"Invalid SRS usage\n"); } - // 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.tpmi = 0; } long get_K2(NR_ServingCellConfigCommon_t *scc, From cc52682bc2778e8b4eee98d01b6fbc5360a2ffc3 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Fri, 10 Jun 2022 16:16:10 +0100 Subject: [PATCH 12/30] Fix SRS stats depending on SRS usage --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 10 ++++++++++ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 10 ++++++---- openair2/LAYER2/NR_MAC_gNB/main.c | 12 ++++++++---- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 +- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 8a373f31f4..c2e08c62de 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2434,6 +2434,12 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr) } } +void reset_srs_stats(NR_UE_info_t *UE) { + if (UE) { + UE->mac_stats.srs_stats[0] = '\0'; + } +} + //------------------------------------------------------------------------------ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup) { @@ -2538,6 +2544,8 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf create_nr_list(&sched_ctrl->feedback_ul_harq, 16); create_nr_list(&sched_ctrl->retrans_ul_harq, 16); + reset_srs_stats(UE); + pthread_mutex_lock(&UE_info->mutex); int i; for(i=0; irrc_processing_timer == 0) { LOG_I(NR_MAC, "(%d.%d) De-activating RRC processing timer for UE %04x\n", frame, slot, UE->rnti); + reset_srs_stats(UE); + const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; NR_CellGroupConfig_t *cg = UE->CellGroup; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 6bbc2c2750..0e47090084 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -785,6 +785,9 @@ void handle_nr_srs_measurements(const module_id_t module_id, return; } + gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; + NR_mac_stats_t *stats = &UE->mac_stats; + switch (srs_ind->srs_usage) { case NR_SRS_ResourceSet__usage_beamManagement: { @@ -809,9 +812,7 @@ void handle_nr_srs_measurements(const module_id_t module_id, } #endif - gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; - NR_mac_stats_t *stats = &UE->mac_stats; - stats->srs_wide_band_snr = (nr_srs_beamforming_report->wide_band_snr>>1)-64; + sprintf(stats->srs_stats,"UL-SNR %i dB", (nr_srs_beamforming_report->wide_band_snr>>1)-64); int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold; uint16_t *ulprbbl = nr_mac->ulprbbl; @@ -836,7 +837,8 @@ void handle_nr_srs_measurements(const module_id_t module_id, NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; ps->srs_feedback.sri = NR_SRS_SRI_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); break; } diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index d65c362a65..5759d058e4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -84,14 +84,14 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp NR_mac_stats_t *stats = &UE->mac_stats; const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0; - stroff+=sprintf(output+stroff,"UE RNTI %04x (%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas), UL-SNR %d dB\n", + stroff+=sprintf(output+stroff,"UE RNTI %04x (%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas)\n", UE->rnti, num++, sched_ctrl->ph, sched_ctrl->pcmax, avg_rsrp, - stats->num_rsrp_meas, - stats->srs_wide_band_snr); + stats->num_rsrp_meas); + stroff+=sprintf(output+stroff,"UE %04x: CQI %d, RI %d, PMI (%d,%d)\n", UE->rnti, UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb, @@ -99,15 +99,19 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1, UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2); + if (stats->srs_stats[0] != '\0') { + stroff+=sprintf(output+stroff,"UE %04x: %s\n", UE->rnti, stats->srs_stats); + } + stroff+=sprintf(output+stroff,"UE %04x: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n", UE->rnti, - stats->dl.rounds[0], stats->dl.rounds[1], stats->dl.rounds[2], stats->dl.rounds[3], stats->dl.errors, stats->pucch0_DTX, sched_ctrl->dl_bler_stats.bler, sched_ctrl->dl_bler_stats.mcs); + if (reset_rsrp) { stats->num_rsrp_meas = 0; stats->cumul_rsrp = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 38dfcce420..078cfadbff 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -694,7 +694,7 @@ typedef struct NR_mac_stats { uint32_t pucch0_DTX; int cumul_rsrp; uint8_t num_rsrp_meas; - int8_t srs_wide_band_snr; + char srs_stats[50]; // Statistics may differ depending on SRS usage } NR_mac_stats_t; typedef struct NR_bler_options { From 5df658141b8fdda2d3f5bb0f2883d27f10b033fd Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Fri, 10 Jun 2022 20:41:22 +0100 Subject: [PATCH 13/30] Implementation of pack and unpack functions for nfapi_nr_srs_normalized_channel_iq_matrix_t --- .../nfapi/public_inc/nfapi_interface.h | 19 +++++ nfapi/open-nFAPI/nfapi/src/nfapi_p7.c | 70 ++++++++++++++++++- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 51 ++++++++++++-- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 1 + .../LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c | 15 ++-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 34 ++++++++- 6 files changed, 175 insertions(+), 15 deletions(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index a7943bb9e5..f14d5220bd 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 e3523884d3..e183736578 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 b5bd6e68ec..ba6c8358e8 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<srs_pdu_list[num_srs].srs_usage = NR_SRS_ResourceSet__usage_beamManagement; + break; + case 1<srs_pdu_list[num_srs].srs_usage = NR_SRS_ResourceSet__usage_codebook; + break; + case 1<srs_pdu_list[num_srs].srs_usage = NR_SRS_ResourceSet__usage_nonCodebook; + break; + case 1<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<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 55e9ff21a7..cb3a7f2118 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 09c1dc17d3..1044072c7a 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<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<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 0e47090084..d075122cfa 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; } From 4a8cc3490ccd3e61fa3c87b886d7c3a99c522474 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 20 Jun 2022 02:20:03 +0100 Subject: [PATCH 14/30] Sending channel matrix to MAC to allow TPMI calculation --- openair1/PHY/TOOLS/tools_defs.h | 5 ++ openair1/SCHED_NR/phy_procedures_nr_gNB.c | 71 +++++++++++++++++++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 7 +- 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 839beb3dc9..6658b96248 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -51,6 +51,11 @@ typedef struct complexf { float i; } cf_t; +typedef struct complex8 { + int8_t r; + int8_t i; +} c8_t; + typedef struct complex16 { int16_t r; int16_t i; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index a24d36aae6..0050f7fc36 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -660,6 +660,55 @@ int fill_srs_reported_symbol_list(nfapi_nr_srs_reported_symbol_t *prgs, return 0; } +int fill_srs_channel_matrix(uint8_t *channel_matrix, + const nfapi_nr_srs_pdu_t *srs_pdu, + const nr_srs_info_t *nr_srs_info, + const uint8_t normalized_iq_representation, + const uint16_t num_gnb_antenna_elements, + const uint16_t num_ue_srs_ports, + const uint16_t prg_size, + const uint16_t num_prgs, + const NR_DL_FRAME_PARMS *frame_parms) { + + const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB; + const uint16_t step = prg_size*NR_NB_SC_PER_RB; + + c16_t *channel_matrix16 = (c16_t*)channel_matrix; + c8_t *channel_matrix8 = (c8_t*)channel_matrix; + + for(int uI = 0; uI < num_ue_srs_ports; uI++) { + for(int gI = 0; gI < num_gnb_antenna_elements; gI++) { + + uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[uI][0]; + if (subcarrier>frame_parms->ofdm_symbol_size) { + subcarrier -= frame_parms->ofdm_symbol_size; + } + + for(int pI = 0; pI < num_prgs; pI++) { + + c16_t *srs_estimated_channel16 = (c16_t *)&nr_srs_info->srs_estimated_channel_freq[gI][uI][subcarrier]; + uint16_t index = uI*num_gnb_antenna_elements*num_prgs + gI*num_prgs + pI; + + if (normalized_iq_representation == 0) { + channel_matrix8[index].r = (int8_t)(srs_estimated_channel16->r>>8); + channel_matrix8[index].i = (int8_t)(srs_estimated_channel16->i>>8); + } else { + channel_matrix16[index].r = srs_estimated_channel16->r; + channel_matrix16[index].i = srs_estimated_channel16->i; + } + + // Subcarrier increment + subcarrier += step; + if (subcarrier >= frame_parms->ofdm_symbol_size) { + subcarrier=subcarrier-frame_parms->ofdm_symbol_size; + } + } + } + } + + return 0; +} + int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { /* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */ int pucch_decode_done = 0; @@ -985,6 +1034,15 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_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; + fill_srs_channel_matrix(nr_srs_normalized_channel_iq_matrix->channel_matrix, + srs_pdu, + gNB->nr_srs_info[i], + nr_srs_normalized_channel_iq_matrix->normalized_iq_representation, + nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements, + nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports, + nr_srs_normalized_channel_iq_matrix->prg_size, + nr_srs_normalized_channel_iq_matrix->num_prgs, + &gNB->frame_parms); #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); @@ -992,6 +1050,19 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { 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); + c16_t *channel_matrix16 = (c16_t*)nr_srs_normalized_channel_iq_matrix->channel_matrix; + c8_t *channel_matrix8 = (c8_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_PHY, "(uI %i, gI %i, pI %i) channel_matrix --> real %i, imag %i\n", + uI, gI, pI, + nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0 ? channel_matrix8[index].r : channel_matrix16[index].r, + nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0 ? channel_matrix8[index].i : channel_matrix16[index].i); + } + } + } #endif gNB->srs_pdu_list[num_srs].report_tlv->length = pack_nr_srs_normalized_channel_iq_matrix(nr_srs_normalized_channel_iq_matrix, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 7025f40fc3..3a6c278adb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -850,13 +850,16 @@ void handle_nr_srs_measurements(const module_id_t module_id, 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; + c16_t *channel_matrix16 = (c16_t*)nr_srs_normalized_channel_iq_matrix->channel_matrix; + c8_t *channel_matrix8 = (c8_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]); + uI, gI, pI, + nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0 ? channel_matrix8[index].r : channel_matrix16[index].r, + nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0 ? channel_matrix8[index].i : channel_matrix16[index].i); } } } From a51e8332cf859b6ea3f843ba22cb53d947603f96 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 21 Jun 2022 21:12:01 +0100 Subject: [PATCH 15/30] TPMI computation for single-layer transmission using two antenna ports --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 10 + openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h | 1 + .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 313 +++++++++++++++++- 3 files changed, 322 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index f5606b32e6..7343b900fa 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -312,6 +312,16 @@ const uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C_dmrs_typeA_pos3[16][4]={ {1,0,2,6} // row index 16 }; +// TS 38.211 - Table 6.3.1.5-1: Precoding matrix W for single-layer transmission using two antenna ports, 'n' = -1 and 'o' = -j +const char table_38211_6_3_1_5_1[6][2][1] = { + {{'1'}, {'0'}},//pmi 0 + {{'0'}, {'1'}}, + {{'1'}, {'1'}}, + {{'1'}, {'n'}}, + {{'1'}, {'j'}}, + {{'1'}, {'o'}} //pmi 5 +}; + void get_info_from_tda_tables(int default_abc, int tda, int dmrs_TypeA_Position, diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h index 4b37c19dff..4829ee15d8 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h @@ -143,4 +143,5 @@ extern const float table_38213_13_12_c3[16]; extern const int32_t table_38213_10_1_1_c2[5]; +extern const char table_38211_6_3_1_5_1[6][2][1]; #endif //DEF_H diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 3a6c278adb..8c72aa4c97 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -764,6 +764,308 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } } +uint32_t calc_power_complex(const int16_t *x, const int16_t *y, const uint32_t size) { + + // Real part value + int64_t sum_x = 0; + int64_t sum_x2 = 0; + for(int k = 0; ktxConfig != NULL && *pusch_Config->txConfig == NR_PUSCH_Config__txConfig_nonCodebook) || + num_ue_srs_ports == 1) { + return max_tpmi; + } + + long max_rank = *pusch_Config->maxRank; + long *ul_FullPowerTransmission = pusch_Config->ext1 ? pusch_Config->ext1->ul_FullPowerTransmission_r16 : NULL; + long *codebookSubset = pusch_Config->codebookSubset; + + if (num_ue_srs_ports == 2) { + + if (max_rank == 1) { + if (ul_FullPowerTransmission && *ul_FullPowerTransmission == NR_PUSCH_Config__ext1__ul_FullPowerTransmission_r16_fullpowerMode1) { + max_tpmi = 2; + } else { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + max_tpmi = 1; + } else { + max_tpmi = 5; + } + } + } else { + if (ul_FullPowerTransmission && *ul_FullPowerTransmission == NR_PUSCH_Config__ext1__ul_FullPowerTransmission_r16_fullpowerMode1) { + max_tpmi = *nrOfLayers == 1 ? 2 : 0; + } else { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + max_tpmi = *nrOfLayers == 1 ? 1 : 0; + } else { + max_tpmi = *nrOfLayers == 1 ? 5 : 2; + } + } + } + + } else if (num_ue_srs_ports == 4) { + + if (max_rank == 1) { + if (ul_FullPowerTransmission && *ul_FullPowerTransmission == NR_PUSCH_Config__ext1__ul_FullPowerTransmission_r16_fullpowerMode1) { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + max_tpmi = 3; + *additional_max_tpmi = 13; + } else { + max_tpmi = 15; + } + } else { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + max_tpmi = 3; + } else if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent) { + max_tpmi = 11; + } else { + max_tpmi = 27; + } + } + } else { + if (ul_FullPowerTransmission && *ul_FullPowerTransmission == NR_PUSCH_Config__ext1__ul_FullPowerTransmission_r16_fullpowerMode1) { + if (max_rank == 2) { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + max_tpmi = *nrOfLayers == 1 ? 3 : 6; + if (*nrOfLayers == 1) { + *additional_max_tpmi = 13; + } + } else { + max_tpmi = *nrOfLayers == 1 ? 15 : 13; + } + } else { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + switch (*nrOfLayers) { + case 1: + max_tpmi = 3; + *additional_max_tpmi = 13; + break; + case 2: + max_tpmi = 6; + break; + case 3: + max_tpmi = 1; + break; + case 4: + max_tpmi = 0; + break; + default: + LOG_E(NR_MAC,"Number of layers %d is invalid!\n", *nrOfLayers); + } + } else { + switch (*nrOfLayers) { + case 1: + max_tpmi = 15; + break; + case 2: + max_tpmi = 13; + break; + case 3: + case 4: + max_tpmi = 2; + break; + default: + LOG_E(NR_MAC,"Number of layers %d is invalid!\n", *nrOfLayers); + } + } + } + } else { + if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + switch (*nrOfLayers) { + case 1: + max_tpmi = 3; + break; + case 2: + max_tpmi = 5; + break; + case 3: + case 4: + max_tpmi = 0; + break; + default: + LOG_E(NR_MAC,"Number of layers %d is invalid!\n", *nrOfLayers); + } + } else if (codebookSubset && *codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent) { + switch (*nrOfLayers) { + case 1: + max_tpmi = 11; + break; + case 2: + max_tpmi = 13; + break; + case 3: + case 4: + max_tpmi = 2; + break; + default: + LOG_E(NR_MAC,"Number of layers %d is invalid!\n", *nrOfLayers); + } + } else { + switch (*nrOfLayers) { + case 1: + max_tpmi = 28; + break; + case 2: + max_tpmi = 22; + break; + case 3: + max_tpmi = 7; + break; + case 4: + max_tpmi = 5; + break; + default: + LOG_E(NR_MAC,"Number of layers %d is invalid!\n", *nrOfLayers); + } + } + } + } + + } + + return max_tpmi; +} + +void get_precoder_matrix_coef(char *w, uint8_t tpmi, uint8_t uI) { + // TODO: Add the remaining tables + *w = *table_38211_6_3_1_5_1[tpmi][uI]; +} + +int nr_srs_tpmi_estimation(const NR_PUSCH_Config_t *pusch_Config, + const uint8_t *channel_matrix, + const uint8_t normalized_iq_representation, + const uint16_t num_gnb_antenna_elements, + const uint16_t num_ue_srs_ports, + const uint16_t prg_size, + const uint16_t num_prgs, + const uint8_t ul_ri) { + + uint8_t tpmi_sel = 0; + int16_t precoded_channel_matrix_re[num_prgs*num_gnb_antenna_elements]; + int16_t precoded_channel_matrix_im[num_prgs*num_gnb_antenna_elements]; + c16_t *channel_matrix16 = (c16_t*)channel_matrix; + uint32_t max_precoded_signal_power = 0; + int additional_max_tpmi = -1; + char w; + + uint8_t max_tpmi = get_max_tpmi(pusch_Config, + num_ue_srs_ports, + &ul_ri, + &additional_max_tpmi); + + uint8_t end_tpmi_loop = additional_max_tpmi > max_tpmi ? additional_max_tpmi : max_tpmi; + + // channel_matrix x precoder_matrix + // [ (gI=0,uI=0) (gI=0,uI=1) ... (gI=0,uI=num_ue_srs_ports-1) ] x [uI=0] + // [ (gI=1,uI=0) (gI=1,uI=1) ... (gI=1,uI=num_ue_srs_ports-1) ] [uI=1] + // [ (gI=2,uI=0) (gI=2,uI=1) ... (gI=2,uI=num_ue_srs_ports-1) ] [uI=2] + // ... ... + + for(uint8_t tpmi = 0; tpmi<=end_tpmi_loop; tpmi++) { + + if (tpmi > max_tpmi) { + tpmi = end_tpmi_loop; + } + + for(int pI = 0; pI real %i, imag %i\n", + uI, gI, pI, channel_matrix16[index].r, channel_matrix16[index].i); +#endif + } + +#ifdef SRS_IND_DEBUG + LOG_I(NR_MAC, "(gI %i, pI %i) precoded_channel_coef --> real %i, imag %i\n", + gI, pI, precoded_channel_matrix_re[index_gI_pI], precoded_channel_matrix_im[index_gI_pI]); +#endif + } + } + + uint32_t precoded_signal_power = calc_power_complex(precoded_channel_matrix_re, + precoded_channel_matrix_im, + num_prgs*num_gnb_antenna_elements); + +#ifdef SRS_IND_DEBUG + LOG_I(NR_MAC, "(tpmi %i) precoded_signal_power = %i\n", tpmi, precoded_signal_power); +#endif + + if (precoded_signal_power > max_precoded_signal_power) { + max_precoded_signal_power = precoded_signal_power; + tpmi_sel = tpmi; + } + } + + return tpmi_sel; +} + void handle_nr_srs_measurements(const module_id_t module_id, const frame_t frame, const sub_frame_t slot, @@ -869,8 +1171,15 @@ void handle_nr_srs_measurements(const module_id_t module_id, 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; + ps->srs_feedback.ul_ri = 0; // TODO: Compute this + ps->srs_feedback.tpmi = nr_srs_tpmi_estimation(ps->pusch_Config, + nr_srs_normalized_channel_iq_matrix->channel_matrix, + nr_srs_normalized_channel_iq_matrix->normalized_iq_representation, + nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements, + nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports, + nr_srs_normalized_channel_iq_matrix->prg_size, + nr_srs_normalized_channel_iq_matrix->num_prgs, + ps->srs_feedback.ul_ri); sprintf(stats->srs_stats,"UL-RI %d, TPMI %d", ps->srs_feedback.ul_ri+1, ps->srs_feedback.tpmi); break; } From b0f554e230e0b1afa7df754e94288922ddb1aeee Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 23 Jun 2022 20:45:55 +0100 Subject: [PATCH 16/30] Fix memory leaks --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 90 +++++++++---------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 74 ++++++++------- 2 files changed, 78 insertions(+), 86 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index de1efc7648..271c3bc2fe 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -990,35 +990,33 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { 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)); - - nr_srs_beamforming_report->prg_size = srs_pdu->beamforming.prg_size; - nr_srs_beamforming_report->num_symbols = 1<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 - nr_srs_beamforming_report->num_reported_symbols = 1<num_symbols; - nr_srs_beamforming_report->prgs = (nfapi_nr_srs_reported_symbol_t*) calloc(1, nr_srs_beamforming_report->num_reported_symbols*sizeof(nfapi_nr_srs_reported_symbol_t)); - fill_srs_reported_symbol_list(&nr_srs_beamforming_report->prgs[0], + nfapi_nr_srs_beamforming_report_t nr_srs_beamforming_report; + nr_srs_beamforming_report.prg_size = srs_pdu->beamforming.prg_size; + nr_srs_beamforming_report.num_symbols = 1<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 + nr_srs_beamforming_report.num_reported_symbols = 1<num_symbols; + nr_srs_beamforming_report.prgs = (nfapi_nr_srs_reported_symbol_t*) calloc(1, nr_srs_beamforming_report.num_reported_symbols*sizeof(nfapi_nr_srs_reported_symbol_t)); + fill_srs_reported_symbol_list(&nr_srs_beamforming_report.prgs[0], srs_pdu, gNB->frame_parms.N_RB_UL, gNB->nr_srs_info[i]->snr_per_rb, srs_est); #ifdef SRS_IND_DEBUG - LOG_I(NR_PHY, "nr_srs_beamforming_report->prg_size = %i\n", nr_srs_beamforming_report->prg_size); - LOG_I(NR_PHY, "nr_srs_beamforming_report->num_symbols = %i\n", nr_srs_beamforming_report->num_symbols); - LOG_I(NR_PHY, "nr_srs_beamforming_report->wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report->wide_band_snr, (nr_srs_beamforming_report->wide_band_snr>>1)-64); - LOG_I(NR_PHY, "nr_srs_beamforming_report->num_reported_symbols = %i\n", nr_srs_beamforming_report->num_reported_symbols); - LOG_I(NR_PHY, "nr_srs_beamforming_report->prgs[0].num_prgs = %i\n", nr_srs_beamforming_report->prgs[0].num_prgs); - for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report->prgs[0].num_prgs; prg_idx++) { - LOG_I(NR_PHY, "nr_srs_beamforming_report->prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n", + LOG_I(NR_PHY, "nr_srs_beamforming_report.prg_size = %i\n", nr_srs_beamforming_report.prg_size); + LOG_I(NR_PHY, "nr_srs_beamforming_report.num_symbols = %i\n", nr_srs_beamforming_report.num_symbols); + LOG_I(NR_PHY, "nr_srs_beamforming_report.wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report.wide_band_snr, (nr_srs_beamforming_report.wide_band_snr>>1)-64); + LOG_I(NR_PHY, "nr_srs_beamforming_report.num_reported_symbols = %i\n", nr_srs_beamforming_report.num_reported_symbols); + LOG_I(NR_PHY, "nr_srs_beamforming_report.prgs[0].num_prgs = %i\n", nr_srs_beamforming_report.prgs[0].num_prgs); + for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report.prgs[0].num_prgs; prg_idx++) { + LOG_I(NR_PHY, "nr_srs_beamforming_report.prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n", prg_idx, - nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr, - (nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr>>1)-64); + nr_srs_beamforming_report.prgs[0].prg_list[prg_idx].rb_snr, + (nr_srs_beamforming_report.prgs[0].prg_list[prg_idx].rb_snr>>1)-64); } #endif - gNB->srs_pdu_list[num_srs].report_tlv->length = pack_nr_srs_beamforming_report(nr_srs_beamforming_report, + gNB->srs_pdu_list[num_srs].report_tlv->length = pack_nr_srs_beamforming_report(&nr_srs_beamforming_report, gNB->srs_pdu_list[num_srs].report_tlv->value, 16384*sizeof(uint32_t)); break; @@ -1026,46 +1024,44 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { 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)); - - 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; - fill_srs_channel_matrix(nr_srs_normalized_channel_iq_matrix->channel_matrix, + nfapi_nr_srs_normalized_channel_iq_matrix_t nr_srs_normalized_channel_iq_matrix; + 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; + fill_srs_channel_matrix(nr_srs_normalized_channel_iq_matrix.channel_matrix, srs_pdu, gNB->nr_srs_info[i], - nr_srs_normalized_channel_iq_matrix->normalized_iq_representation, - nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements, - nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports, - nr_srs_normalized_channel_iq_matrix->prg_size, - nr_srs_normalized_channel_iq_matrix->num_prgs, + nr_srs_normalized_channel_iq_matrix.normalized_iq_representation, + nr_srs_normalized_channel_iq_matrix.num_gnb_antenna_elements, + nr_srs_normalized_channel_iq_matrix.num_ue_srs_ports, + nr_srs_normalized_channel_iq_matrix.prg_size, + nr_srs_normalized_channel_iq_matrix.num_prgs, &gNB->frame_parms); #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); - c16_t *channel_matrix16 = (c16_t*)nr_srs_normalized_channel_iq_matrix->channel_matrix; - c8_t *channel_matrix8 = (c8_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_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); + c16_t *channel_matrix16 = (c16_t*)nr_srs_normalized_channel_iq_matrix.channel_matrix; + c8_t *channel_matrix8 = (c8_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_PHY, "(uI %i, gI %i, pI %i) channel_matrix --> real %i, imag %i\n", uI, gI, pI, - nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0 ? channel_matrix8[index].r : channel_matrix16[index].r, - nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0 ? channel_matrix8[index].i : channel_matrix16[index].i); + nr_srs_normalized_channel_iq_matrix.normalized_iq_representation == 0 ? channel_matrix8[index].r : channel_matrix16[index].r, + nr_srs_normalized_channel_iq_matrix.normalized_iq_representation == 0 ? channel_matrix8[index].i : channel_matrix16[index].i); } } } #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->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)); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 8c72aa4c97..f7cf2cc4b9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1096,37 +1096,35 @@ 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; unpack_nr_srs_beamforming_report(srs_ind->report_tlv->value, srs_ind->report_tlv->length, - nr_srs_beamforming_report, + &nr_srs_beamforming_report, sizeof(nfapi_nr_srs_beamforming_report_t)); #ifdef SRS_IND_DEBUG - LOG_I(NR_MAC, "nr_srs_beamforming_report->prg_size = %i\n", nr_srs_beamforming_report->prg_size); - LOG_I(NR_MAC, "nr_srs_beamforming_report->num_symbols = %i\n", nr_srs_beamforming_report->num_symbols); - LOG_I(NR_MAC, "nr_srs_beamforming_report->wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report->wide_band_snr, (nr_srs_beamforming_report->wide_band_snr>>1)-64); - LOG_I(NR_MAC, "nr_srs_beamforming_report->num_reported_symbols = %i\n", nr_srs_beamforming_report->num_reported_symbols); - LOG_I(NR_MAC, "nr_srs_beamforming_report->prgs[0].num_prgs = %i\n", nr_srs_beamforming_report->prgs[0].num_prgs); - for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report->prgs[0].num_prgs; prg_idx++) { - LOG_I(NR_MAC, "nr_srs_beamforming_report->prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n", + LOG_I(NR_MAC, "nr_srs_beamforming_report.prg_size = %i\n", nr_srs_beamforming_report.prg_size); + LOG_I(NR_MAC, "nr_srs_beamforming_report.num_symbols = %i\n", nr_srs_beamforming_report.num_symbols); + LOG_I(NR_MAC, "nr_srs_beamforming_report.wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report.wide_band_snr, (nr_srs_beamforming_report.wide_band_snr>>1)-64); + LOG_I(NR_MAC, "nr_srs_beamforming_report.num_reported_symbols = %i\n", nr_srs_beamforming_report.num_reported_symbols); + LOG_I(NR_MAC, "nr_srs_beamforming_report.prgs[0].num_prgs = %i\n", nr_srs_beamforming_report.prgs[0].num_prgs); + for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report.prgs[0].num_prgs; prg_idx++) { + LOG_I(NR_MAC, "nr_srs_beamforming_report.prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n", prg_idx, - nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr, - (nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr>>1)-64); + nr_srs_beamforming_report.prgs[0].prg_list[prg_idx].rb_snr, + (nr_srs_beamforming_report.prgs[0].prg_list[prg_idx].rb_snr>>1)-64); } #endif - sprintf(stats->srs_stats,"UL-SNR %i dB", (nr_srs_beamforming_report->wide_band_snr>>1)-64); + sprintf(stats->srs_stats,"UL-SNR %i dB", (nr_srs_beamforming_report.wide_band_snr>>1)-64); const int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold; uint16_t *ulprbbl = nr_mac->ulprbbl; - uint8_t num_rbs = nr_srs_beamforming_report->prg_size * nr_srs_beamforming_report->prgs[0].num_prgs; + uint8_t num_rbs = nr_srs_beamforming_report.prg_size * nr_srs_beamforming_report.prgs[0].num_prgs; memset(ulprbbl, 0, num_rbs*sizeof(uint16_t)); for (int rb = 0; rb < num_rbs; rb++) { - int snr = (nr_srs_beamforming_report->prgs[0].prg_list[rb/nr_srs_beamforming_report->prg_size].rb_snr>>1)-64; + int snr = (nr_srs_beamforming_report.prgs[0].prg_list[rb/nr_srs_beamforming_report.prg_size].rb_snr>>1)-64; if (snr < ul_prbblack_SNR_threshold) { ulprbbl[rb] = 0x3FFF; // all symbols taken } @@ -1138,30 +1136,28 @@ 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)); - + nfapi_nr_srs_normalized_channel_iq_matrix_t nr_srs_normalized_channel_iq_matrix; unpack_nr_srs_normalized_channel_iq_matrix(srs_ind->report_tlv->value, srs_ind->report_tlv->length, - nr_srs_normalized_channel_iq_matrix, + &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); - c16_t *channel_matrix16 = (c16_t*)nr_srs_normalized_channel_iq_matrix->channel_matrix; - c8_t *channel_matrix8 = (c8_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, "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); + c16_t *channel_matrix16 = (c16_t*)nr_srs_normalized_channel_iq_matrix.channel_matrix; + c8_t *channel_matrix8 = (c8_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, - nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0 ? channel_matrix8[index].r : channel_matrix16[index].r, - nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0 ? channel_matrix8[index].i : channel_matrix16[index].i); + nr_srs_normalized_channel_iq_matrix.normalized_iq_representation == 0 ? channel_matrix8[index].r : channel_matrix16[index].r, + nr_srs_normalized_channel_iq_matrix.normalized_iq_representation == 0 ? channel_matrix8[index].i : channel_matrix16[index].i); } } } @@ -1173,12 +1169,12 @@ void handle_nr_srs_measurements(const module_id_t module_id, ps->srs_feedback.sri = NR_SRS_SRI_0; ps->srs_feedback.ul_ri = 0; // TODO: Compute this ps->srs_feedback.tpmi = nr_srs_tpmi_estimation(ps->pusch_Config, - nr_srs_normalized_channel_iq_matrix->channel_matrix, - nr_srs_normalized_channel_iq_matrix->normalized_iq_representation, - nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements, - nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports, - nr_srs_normalized_channel_iq_matrix->prg_size, - nr_srs_normalized_channel_iq_matrix->num_prgs, + nr_srs_normalized_channel_iq_matrix.channel_matrix, + nr_srs_normalized_channel_iq_matrix.normalized_iq_representation, + nr_srs_normalized_channel_iq_matrix.num_gnb_antenna_elements, + nr_srs_normalized_channel_iq_matrix.num_ue_srs_ports, + nr_srs_normalized_channel_iq_matrix.prg_size, + nr_srs_normalized_channel_iq_matrix.num_prgs, ps->srs_feedback.ul_ri); sprintf(stats->srs_stats,"UL-RI %d, TPMI %d", ps->srs_feedback.ul_ri+1, ps->srs_feedback.tpmi); break; From 6056e854e1bcc9860053815eeef772ebd7fe47a6 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Sat, 25 Jun 2022 18:07:09 +0100 Subject: [PATCH 17/30] Get TPMI up 4 antenna ports and 1 layer --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 76 +++++++++++++++++-- openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h | 2 + .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 26 ++++++- 3 files changed, 94 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 7343b900fa..d9c39fa171 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -314,12 +314,76 @@ const uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C_dmrs_typeA_pos3[16][4]={ // TS 38.211 - Table 6.3.1.5-1: Precoding matrix W for single-layer transmission using two antenna ports, 'n' = -1 and 'o' = -j const char table_38211_6_3_1_5_1[6][2][1] = { - {{'1'}, {'0'}},//pmi 0 - {{'0'}, {'1'}}, - {{'1'}, {'1'}}, - {{'1'}, {'n'}}, - {{'1'}, {'j'}}, - {{'1'}, {'o'}} //pmi 5 + {{'1'}, {'0'}}, // tpmi 0 + {{'0'}, {'1'}}, // tpmi 1 + {{'1'}, {'1'}}, // tpmi 2 + {{'1'}, {'n'}}, // tpmi 3 + {{'1'}, {'j'}}, // tpmi 4 + {{'1'}, {'o'}} // tpmi 5 +}; + +// TS 38.211 - Table 6.3.1.5-2: Precoding matrix W for single-layer transmission using four antenna ports with transform precoding enabled, 'n' = -1 and 'o' = -j +const char table_38211_6_3_1_5_2[28][4][1] = { + {{'1'}, {'0'}, {'0'}, {'0'}}, // tpmi 0 + {{'0'}, {'1'}, {'0'}, {'0'}}, // tpmi 1 + {{'0'}, {'0'}, {'1'}, {'0'}}, // tpmi 2 + {{'0'}, {'0'}, {'0'}, {'1'}}, // tpmi 3 + {{'1'}, {'0'}, {'1'}, {'0'}}, // tpmi 4 + {{'1'}, {'0'}, {'n'}, {'0'}}, // tpmi 5 + {{'1'}, {'0'}, {'j'}, {'0'}}, // tpmi 6 + {{'1'}, {'0'}, {'o'}, {'0'}}, // tpmi 7 + {{'0'}, {'1'}, {'0'}, {'1'}}, // tpmi 8 + {{'0'}, {'1'}, {'0'}, {'n'}}, // tpmi 9 + {{'0'}, {'1'}, {'0'}, {'j'}}, // tpmi 10 + {{'0'}, {'1'}, {'0'}, {'o'}}, // tpmi 11 + {{'1'}, {'1'}, {'1'}, {'n'}}, // tpmi 12 + {{'1'}, {'1'}, {'j'}, {'j'}}, // tpmi 13 + {{'1'}, {'1'}, {'n'}, {'1'}}, // tpmi 14 + {{'1'}, {'1'}, {'o'}, {'o'}}, // tpmi 15 + {{'1'}, {'j'}, {'1'}, {'j'}}, // tpmi 16 + {{'1'}, {'j'}, {'j'}, {'1'}}, // tpmi 17 + {{'1'}, {'j'}, {'n'}, {'o'}}, // tpmi 18 + {{'1'}, {'j'}, {'o'}, {'n'}}, // tpmi 19 + {{'1'}, {'n'}, {'1'}, {'1'}}, // tpmi 20 + {{'1'}, {'n'}, {'j'}, {'o'}}, // tpmi 21 + {{'1'}, {'n'}, {'n'}, {'n'}}, // tpmi 22 + {{'1'}, {'n'}, {'o'}, {'j'}}, // tpmi 23 + {{'1'}, {'o'}, {'1'}, {'o'}}, // tpmi 24 + {{'1'}, {'o'}, {'j'}, {'n'}}, // tpmi 25 + {{'1'}, {'o'}, {'n'}, {'j'}}, // tpmi 26 + {{'1'}, {'o'}, {'o'}, {'1'}} // tpmi 27 +}; + +// TS 38.211 - Table 6.3.1.5-3: Precoding matrix W for single-layer transmission using four antenna ports with transform precoding disabled, 'n' = -1 and 'o' = -j +const char table_38211_6_3_1_5_3[28][4][1] = { + {{'1'}, {'0'}, {'0'}, {'0'}}, // tpmi 0 + {{'0'}, {'1'}, {'0'}, {'0'}}, // tpmi 1 + {{'0'}, {'0'}, {'1'}, {'0'}}, // tpmi 2 + {{'0'}, {'0'}, {'0'}, {'1'}}, // tpmi 3 + {{'1'}, {'0'}, {'1'}, {'0'}}, // tpmi 4 + {{'1'}, {'0'}, {'n'}, {'0'}}, // tpmi 5 + {{'1'}, {'0'}, {'j'}, {'0'}}, // tpmi 6 + {{'1'}, {'0'}, {'o'}, {'0'}}, // tpmi 7 + {{'0'}, {'1'}, {'0'}, {'1'}}, // tpmi 8 + {{'0'}, {'1'}, {'0'}, {'n'}}, // tpmi 9 + {{'0'}, {'1'}, {'0'}, {'j'}}, // tpmi 10 + {{'0'}, {'1'}, {'0'}, {'o'}}, // tpmi 11 + {{'1'}, {'1'}, {'1'}, {'1'}}, // tpmi 12 + {{'1'}, {'1'}, {'j'}, {'j'}}, // tpmi 13 + {{'1'}, {'1'}, {'n'}, {'n'}}, // tpmi 14 + {{'1'}, {'1'}, {'o'}, {'o'}}, // tpmi 15 + {{'1'}, {'j'}, {'1'}, {'j'}}, // tpmi 16 + {{'1'}, {'j'}, {'j'}, {'n'}}, // tpmi 17 + {{'1'}, {'j'}, {'n'}, {'o'}}, // tpmi 18 + {{'1'}, {'j'}, {'o'}, {'1'}}, // tpmi 19 + {{'1'}, {'n'}, {'1'}, {'n'}}, // tpmi 20 + {{'1'}, {'n'}, {'j'}, {'o'}}, // tpmi 21 + {{'1'}, {'n'}, {'n'}, {'1'}}, // tpmi 22 + {{'1'}, {'n'}, {'o'}, {'j'}}, // tpmi 23 + {{'1'}, {'o'}, {'1'}, {'o'}}, // tpmi 24 + {{'1'}, {'o'}, {'j'}, {'1'}}, // tpmi 25 + {{'1'}, {'o'}, {'n'}, {'j'}}, // tpmi 26 + {{'1'}, {'o'}, {'o'}, {'n'}} // tpmi 27 }; void get_info_from_tda_tables(int default_abc, diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h index 4829ee15d8..51b6eaefcd 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h @@ -144,4 +144,6 @@ extern const float table_38213_13_12_c3[16]; extern const int32_t table_38213_10_1_1_c2[5]; extern const char table_38211_6_3_1_5_1[6][2][1]; +extern const char table_38211_6_3_1_5_2[28][4][1]; +extern const char table_38211_6_3_1_5_3[28][4][1]; #endif //DEF_H diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index f7cf2cc4b9..d9a595b9e7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -979,12 +979,29 @@ uint8_t get_max_tpmi(const NR_PUSCH_Config_t *pusch_Config, return max_tpmi; } -void get_precoder_matrix_coef(char *w, uint8_t tpmi, uint8_t uI) { - // TODO: Add the remaining tables - *w = *table_38211_6_3_1_5_1[tpmi][uI]; +void get_precoder_matrix_coef(char *w, + const uint8_t ul_ri, + const uint16_t num_ue_srs_ports, + const uint8_t transform_precoding, + const uint8_t tpmi, + const uint8_t uI) { + if (ul_ri == 0) { + if (num_ue_srs_ports == 2) { + *w = *table_38211_6_3_1_5_1[tpmi][uI]; + } else { + if (transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) { + *w = *table_38211_6_3_1_5_2[tpmi][uI]; + } else { + *w = *table_38211_6_3_1_5_3[tpmi][uI]; + } + } + } else { + AssertFatal(1==0,"Function get_precoder_matrix_coef() does not support %i layers yet!\n", ul_ri+1); + } } int nr_srs_tpmi_estimation(const NR_PUSCH_Config_t *pusch_Config, + const uint8_t transform_precoding, const uint8_t *channel_matrix, const uint8_t normalized_iq_representation, const uint16_t num_gnb_antenna_elements, @@ -1030,7 +1047,7 @@ int nr_srs_tpmi_estimation(const NR_PUSCH_Config_t *pusch_Config, for(int uI = 0; uI < num_ue_srs_ports; uI++) { uint16_t index = uI*num_gnb_antenna_elements*num_prgs + index_gI_pI; - get_precoder_matrix_coef(&w, tpmi, uI); + get_precoder_matrix_coef(&w, ul_ri, num_ue_srs_ports, transform_precoding, tpmi, uI); c16_t h_times_w = nr_h_times_w(channel_matrix16[index], w); precoded_channel_matrix_re[index_gI_pI] += h_times_w.r; @@ -1169,6 +1186,7 @@ void handle_nr_srs_measurements(const module_id_t module_id, ps->srs_feedback.sri = NR_SRS_SRI_0; ps->srs_feedback.ul_ri = 0; // TODO: Compute this ps->srs_feedback.tpmi = nr_srs_tpmi_estimation(ps->pusch_Config, + ps->transform_precoding, nr_srs_normalized_channel_iq_matrix.channel_matrix, nr_srs_normalized_channel_iq_matrix.normalized_iq_representation, nr_srs_normalized_channel_iq_matrix.num_gnb_antenna_elements, From 7e707eff5a1560730c321d436bebc40704591070 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 4 Jul 2022 11:12:32 +0100 Subject: [PATCH 18/30] Fix nr_pbchsim build --- openair1/SIMULATION/NR_PHY/pbchsim.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 07c5f118dc..b05fc8ba2d 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -98,6 +98,14 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, return false; } +int pack_nr_srs_beamforming_report(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen) { + return 0; +} + +int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen) { + return 0; +} + void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, int N_RB_DL, int N_RB_UL, From 384fad9e8a2859df13792cc20c017f0bd3960ec4 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Fri, 22 Jul 2022 12:04:21 +0100 Subject: [PATCH 19/30] Align memory in srs_estimated_channel_freq and srs_estimated_channel_time --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 2a6ff37b4c..9f59df2f80 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -908,8 +908,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { uint8_t N_symb_SRS = 1<num_symbols; int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS]; int32_t srs_ls_estimated_channel[frame_parms->nb_antennas_rx][MAX_NUM_NR_SRS_AP][frame_parms->ofdm_symbol_size*N_symb_SRS]; - int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][MAX_NUM_NR_SRS_AP][frame_parms->ofdm_symbol_size*N_symb_SRS]; - int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][MAX_NUM_NR_SRS_AP][frame_parms->ofdm_symbol_size]; + int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][MAX_NUM_NR_SRS_AP][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32))); + int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][MAX_NUM_NR_SRS_AP][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32))); int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][MAX_NUM_NR_SRS_AP][frame_parms->ofdm_symbol_size]; uint32_t noise_power_per_rb[srs_pdu->bwp_size]; int8_t snr_per_rb[srs_pdu->bwp_size]; From 1504e9256b400ad3e9d2242d284815b0e893cb13 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 8 Aug 2022 15:11:18 +0100 Subject: [PATCH 20/30] Fix build after merge --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 7148d7af2c..f3ac2ca501 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1174,11 +1174,12 @@ void handle_nr_srs_measurements(const module_id_t module_id, // TODO: This should be improved NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; 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; // TODO: Compute this - ps->srs_feedback.tpmi = nr_srs_tpmi_estimation(ps->pusch_Config, - ps->transform_precoding, + ps->srs_feedback.tpmi = nr_srs_tpmi_estimation(current_BWP->pusch_Config, + current_BWP->transform_precoding, nr_srs_normalized_channel_iq_matrix.channel_matrix, nr_srs_normalized_channel_iq_matrix.normalized_iq_representation, nr_srs_normalized_channel_iq_matrix.num_gnb_antenna_elements, From 65b56db9ec92f1cf28bc9dc60200eadf0f7544af Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 8 Aug 2022 16:07:58 +0100 Subject: [PATCH 21/30] Move srs_ls_estimated_channel[] to nr_srs_channel_estimation() function --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 23 +++++++++---------- openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h | 1 - openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 -- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index bc29298f0a..89e935528b 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -967,7 +967,6 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, const nr_srs_info_t *nr_srs_info, const int32_t **srs_generated_signal, int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_ls_estimated_channel[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], int32_t srs_estimated_channel_freq[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], int32_t srs_estimated_channel_time[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], int32_t srs_estimated_channel_time_shifted[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], @@ -993,18 +992,17 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, fd_cdm = 2; } + c16_t srs_ls_estimated_channel[frame_parms->ofdm_symbol_size*(1<num_symbols)]; int16_t ch_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; int16_t ch_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; int16_t noise_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; int16_t noise_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; - int16_t ls_estimated[2]; for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { for (int p_index = 0; p_index < N_ap; p_index++) { - memset(srs_ls_estimated_channel[ant][p_index], 0, frame_parms->ofdm_symbol_size*(1<num_symbols)*sizeof(int32_t)); memset(srs_estimated_channel_freq[ant][p_index], 0, frame_parms->ofdm_symbol_size*(1<num_symbols)*sizeof(int32_t)); #ifdef SRS_DEBUG @@ -1047,7 +1045,8 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, } } - srs_ls_estimated_channel[ant][p_index][subcarrier] = ls_estimated[0] + (((int32_t)ls_estimated[1] << 16) & 0xFFFF0000); + srs_ls_estimated_channel[subcarrier].r = ls_estimated[0]; + srs_ls_estimated_channel[subcarrier].i = ls_estimated[1]; #ifdef SRS_DEBUG int subcarrier_log = subcarrier-subcarrier_offset; @@ -1060,8 +1059,8 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, } LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", subcarrier_log, - (int16_t)(srs_generated_signal[p_index][subcarrier] & 0xFFFF), (int16_t)((srs_generated_signal[p_index][subcarrier] >> 16) & 0xFFFF), - (int16_t)(srs_received_signal[ant][subcarrier] & 0xFFFF), (int16_t)((srs_received_signal[ant][subcarrier] >> 16) & 0xFFFF), + ((c16_t*)srs_generated_signal[p_index])[subcarrier].r, ((c16_t*)srs_generated_signal[p_index])[subcarrier].i, + ((c16_t*)srs_received_signal[ant])[subcarrier].r, ((c16_t*)srs_received_signal[ant])[subcarrier].i, ls_estimated[0], ls_estimated[1]); #endif @@ -1120,8 +1119,8 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, for (int k = 0; k < M_sc_b_SRS; k++) { ch_real[base_idx+k] = ((c16_t*)srs_estimated_channel_freq[ant][p_index])[subcarrier].r; ch_imag[base_idx+k] = ((c16_t*)srs_estimated_channel_freq[ant][p_index])[subcarrier].i; - noise_real[base_idx+k] = abs(((c16_t*)srs_ls_estimated_channel[ant][p_index])[subcarrier].r - ch_real[base_idx+k]); - noise_imag[base_idx+k] = abs(((c16_t*)srs_ls_estimated_channel[ant][p_index])[subcarrier].i - ch_imag[base_idx+k]); + noise_real[base_idx+k] = abs(srs_ls_estimated_channel[subcarrier].r - ch_real[base_idx+k]); + noise_imag[base_idx+k] = abs(srs_ls_estimated_channel[subcarrier].i - ch_imag[base_idx+k]); subcarrier += K_TC; if (subcarrier >= frame_parms->ofdm_symbol_size) { subcarrier=subcarrier-frame_parms->ofdm_symbol_size; @@ -1148,10 +1147,10 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", subcarrier_log, - (int16_t)(srs_ls_estimated_channel[ant][p_index][subcarrier]&0xFFFF), - (int16_t)((srs_ls_estimated_channel[ant][p_index][subcarrier]>>16)&0xFFFF), - (int16_t)(srs_estimated_channel_freq[ant][p_index][subcarrier]&0xFFFF), - (int16_t)((srs_estimated_channel_freq[ant][p_index][subcarrier]>>16)&0xFFFF), + srs_ls_estimated_channel[subcarrier].r, + srs_ls_estimated_channel[subcarrier].i, + ((c16_t*)srs_estimated_channel_freq[ant][p_index])[subcarrier].r, + ((c16_t*)srs_estimated_channel_freq[ant][p_index])[subcarrier].i, noise_real[base_idx+(k/K_TC)], noise_imag[base_idx+(k/K_TC)]); // Subcarrier increment diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index f00db212f7..df4dcbbaa2 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -73,7 +73,6 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, const nr_srs_info_t *nr_srs_info, const int32_t **srs_generated_signal, int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_ls_estimated_channel[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], int32_t srs_estimated_channel_freq[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], int32_t srs_estimated_channel_time[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], int32_t srs_estimated_channel_time_shifted[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index f971f49942..e4b558c4ff 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -882,7 +882,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu; uint8_t N_symb_SRS = 1<num_symbols; int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS]; - int32_t srs_ls_estimated_channel[frame_parms->nb_antennas_rx][1<num_ant_ports][frame_parms->ofdm_symbol_size*N_symb_SRS]; int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][1<num_ant_ports][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32))); int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][1<num_ant_ports][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32))); int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][1<num_ant_ports][frame_parms->ofdm_symbol_size]; @@ -907,7 +906,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { gNB->nr_srs_info[i], (const int32_t **) gNB->nr_srs_info[i]->srs_generated_signal, srs_received_signal, - srs_ls_estimated_channel, srs_estimated_channel_freq, srs_estimated_channel_time, srs_estimated_channel_time_shifted, From e5133cf6690df7d084c79ad81d33b87a849c5440 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 8 Aug 2022 16:25:50 +0100 Subject: [PATCH 22/30] Move more variables to nr_srs_channel_estimation() function --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 25 +++++++++---------- openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h | 3 --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 6 ----- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 89e935528b..e78d604f6c 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -970,9 +970,6 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, int32_t srs_estimated_channel_freq[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], int32_t srs_estimated_channel_time[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], int32_t srs_estimated_channel_time_shifted[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - uint32_t *signal_power, - uint32_t *noise_power_per_rb, - uint32_t *noise_power, int8_t *snr_per_rb, int8_t *snr) { @@ -993,6 +990,7 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, } c16_t srs_ls_estimated_channel[frame_parms->ofdm_symbol_size*(1<num_symbols)]; + uint32_t noise_power_per_rb[srs_pdu->bwp_size]; int16_t ch_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; int16_t ch_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; int16_t noise_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS]; @@ -1003,6 +1001,7 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, for (int p_index = 0; p_index < N_ap; p_index++) { + memset(srs_ls_estimated_channel, 0, frame_parms->ofdm_symbol_size*(1<num_symbols)*sizeof(c16_t)); memset(srs_estimated_channel_freq[ant][p_index], 0, frame_parms->ofdm_symbol_size*(1<num_symbols)*sizeof(int32_t)); #ifdef SRS_DEBUG @@ -1178,21 +1177,21 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, } // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) // Compute signal power - *signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS) - + calc_power(ch_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS); + uint32_t signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS) + + calc_power(ch_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS); #ifdef SRS_DEBUG - LOG_I(NR_PHY,"signal_power = %u\n", *signal_power); + LOG_I(NR_PHY,"signal_power = %u\n", signal_power); #endif - if (*signal_power == 0) { + if (signal_power == 0) { LOG_W(NR_PHY, "Received SRS signal power is 0\n"); return -1; } // Compute noise power - const uint8_t signal_power_bits = log2_approx(*signal_power); + const uint8_t signal_power_bits = log2_approx(signal_power); const uint8_t factor_bits = signal_power_bits < 32 ? 32 - signal_power_bits : 0; // 32 due to input of dB_fixed(uint32_t x) const int32_t factor_dB = dB_fixed(1<nb_antennas_rx*N_ap*M_sc_b_SRS) - + calc_power(noise_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS); + uint32_t noise_power = calc_power(noise_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS) + + calc_power(noise_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS); - *snr = dB_fixed((int32_t)((*signal_power<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], int32_t srs_estimated_channel_time[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], int32_t srs_estimated_channel_time_shifted[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - uint32_t *signal_power, - uint32_t *noise_power_per_rb, - uint32_t *noise_power, int8_t *snr_per_rb, int8_t *snr); #endif diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index e4b558c4ff..9e888cab89 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -885,10 +885,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][1<num_ant_ports][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32))); int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][1<num_ant_ports][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32))); int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][1<num_ant_ports][frame_parms->ofdm_symbol_size]; - uint32_t noise_power_per_rb[srs_pdu->bwp_size]; int8_t snr_per_rb[srs_pdu->bwp_size]; - uint32_t signal_power; - uint32_t noise_power; int8_t snr; // At least currently, the configuration is constant, so it is enough to generate the sequence just once. @@ -909,9 +906,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { srs_estimated_channel_freq, srs_estimated_channel_time, srs_estimated_channel_time_shifted, - &signal_power, - noise_power_per_rb, - &noise_power, snr_per_rb, &snr); } From 5d9f91f6a3e4e77e709109379ecd3b41dd282158 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Wed, 10 Aug 2022 19:53:57 +0100 Subject: [PATCH 23/30] Fix input in fill_srs_channel_matrix() function --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 9e888cab89..1eeacf9da3 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -643,7 +643,7 @@ int fill_srs_channel_matrix(uint8_t *channel_matrix, const uint16_t prg_size, const uint16_t num_prgs, const NR_DL_FRAME_PARMS *frame_parms, - const int32_t srs_estimated_channel_freq[][MAX_NUM_NR_SRS_AP][frame_parms->ofdm_symbol_size*(1<num_symbols)]) { + const int32_t srs_estimated_channel_freq[][1<num_ant_ports][frame_parms->ofdm_symbol_size*(1<num_symbols)]) { const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB; const uint16_t step = prg_size*NR_NB_SC_PER_RB; From f71f8b5afc26bb9c3a13f2303b020f52a622defb Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 12 Sep 2022 20:03:43 +0100 Subject: [PATCH 24/30] Removing NR_CellGroupConfig_t *cg input from config_uldci() function --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 47 +++++++++---------- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 1 - .../NR_MAC_gNB/gNB_scheduler_primitives.c | 11 +---- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 1 - openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 - 6 files changed, 25 insertions(+), 38 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index e764ba81e7..8fa6dd3f86 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2728,12 +2728,13 @@ uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config, return n_antenna_port; } -//#define DEBUG_SRS_RESOURCE_IND -uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, +// #define DEBUG_SRS_RESOURCE_IND +uint8_t compute_srs_resource_indicator(NR_PUSCH_ServingCellConfig_t *pusch_servingcellconfig, NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, nr_srs_feedback_t *srs_feedback, - uint16_t *val) { + uint16_t *val) +{ uint8_t nbits = 0; // SRI occupies a number of bits which is dependent upon the uplink transmission scheme, and it is used to determine @@ -2793,19 +2794,19 @@ uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, // - otherwise, Lmax is given by the maximum number of layers for PUSCH supported by the UE for the serving cell // for non-codebook based operation. int Lmax = 0; - if (uplinkConfig && uplinkConfig->pusch_ServingCellConfig != NULL) { - if (uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers != NULL) { - Lmax = *uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers; + if (pusch_servingcellconfig != NULL) { + if (pusch_servingcellconfig->ext1->maxMIMO_Layers != NULL) { + Lmax = *pusch_servingcellconfig->ext1->maxMIMO_Layers; } else { - AssertFatal(1==0,"MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); + AssertFatal(1 == 0, "MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); } } else { - AssertFatal(1==0,"MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); + AssertFatal(1 == 0, "MIMO on PUSCH not supported, maxMIMO_Layers needs to be set to 1\n"); } int lmin = 0; int lsum = 0; int count = 0; - for (int i=0; isrs_ResourceSetToAddModList->list.count; i++) { + for (int i = 0; i < srs_config->srs_ResourceSetToAddModList->list.count; i++) { if (srs_config->srs_ResourceSetToAddModList->list.array[i]->usage == NR_SRS_ResourceSet__usage_nonCodebook) { count++; } @@ -3222,37 +3223,35 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, size += 1; } // 1st DAI - if (cg->physicalCellGroupConfig && - cg->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook==NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic) + if (cg->physicalCellGroupConfig && cg->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook == NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic) dci_pdu->dai[0].nbits = 2; else dci_pdu->dai[0].nbits = 1; size += dci_pdu->dai[0].nbits; - LOG_D(NR_MAC,"DAI1 nbits %d\n",dci_pdu->dai[0].nbits); + LOG_D(NR_MAC, "DAI1 nbits %d\n", dci_pdu->dai[0].nbits); // 2nd DAI - if (cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig && - cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup && - cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) { //TODO not sure about that + if (cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig && cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup + && cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) { // TODO not sure about that dci_pdu->dai[1].nbits = 2; size += dci_pdu->dai[1].nbits; } // SRS resource indicator - dci_pdu->srs_resource_indicator.nbits = compute_srs_resource_indicator(uplinkConfig, pusch_Config, srs_config, NULL, NULL); + NR_PUSCH_ServingCellConfig_t *pusch_servingcellconfig = uplinkConfig && uplinkConfig->pusch_ServingCellConfig ? uplinkConfig->pusch_ServingCellConfig->choice.setup : NULL; + dci_pdu->srs_resource_indicator.nbits = compute_srs_resource_indicator(pusch_servingcellconfig, pusch_Config, srs_config, NULL, NULL); size += dci_pdu->srs_resource_indicator.nbits; - LOG_D(NR_MAC,"dci_pdu->srs_resource_indicator.nbits %d\n", dci_pdu->srs_resource_indicator.nbits); + LOG_D(NR_MAC, "dci_pdu->srs_resource_indicator.nbits %d\n", dci_pdu->srs_resource_indicator.nbits); // Precoding info and number of layers dci_pdu->precoding_information.nbits = compute_precoding_information(pusch_Config, srs_config, dci_pdu->srs_resource_indicator, NULL, NULL, NULL); size += dci_pdu->precoding_information.nbits; - LOG_D(NR_MAC,"dci_pdu->precoding_informaiton.nbits=%d\n",dci_pdu->precoding_information.nbits); + LOG_D(NR_MAC, "dci_pdu->precoding_informaiton.nbits=%d\n", dci_pdu->precoding_information.nbits); // Antenna ports - long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwpd, (uint8_t*)&format, rnti_type, 0); + long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwpd, (uint8_t *)&format, rnti_type, 0); NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = NULL; - int xa=0; - int xb=0; - if(pusch_Config && - pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL){ + int xa = 0; + int xb = 0; + if (pusch_Config && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL) { NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup; - xa = ul_ant_bits(NR_DMRS_UplinkConfig,transformPrecoder); + xa = ul_ant_bits(NR_DMRS_UplinkConfig, transformPrecoder); } if(pusch_Config && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB != NULL){ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index eec9522af9..573d4c004e 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -50,7 +50,7 @@ int is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,slo int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP, frame_type_t frame_type); -uint8_t compute_srs_resource_indicator(NR_UplinkConfig_t *uplinkConfig, +uint8_t compute_srs_resource_indicator(NR_PUSCH_ServingCellConfig_t *pusch_servingcellconfig, NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, nr_srs_feedback_t *srs_feedback, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 87770d0701..52ed621c36 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -827,7 +827,6 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t const NR_SIB1_t *sib1 = cc->sib1 ? cc->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; config_uldci(sib1, scc, - NULL, pusch_pdu, &uldci_payload, NULL, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index e324ec1520..a8598458c1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -883,7 +883,6 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, void config_uldci(const NR_SIB1_t *sib1, const NR_ServingCellConfigCommon_t *scc, - const NR_CellGroupConfig_t *cg, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, nr_srs_feedback_t *srs_feedback, @@ -921,15 +920,7 @@ void config_uldci(const NR_SIB1_t *sib1, pusch_Config->txConfig != NULL) { AssertFatal(*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook, "Non Codebook configuration non supported\n"); - NR_UplinkConfig_t *uplinkConfig = NULL; - if (cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated) { - uplinkConfig = cg->spCellConfig->spCellConfigDedicated->uplinkConfig; - } - compute_srs_resource_indicator(uplinkConfig, - pusch_Config, - ul_bwp->srs_Config, - srs_feedback, - &dci_pdu_rel15->srs_resource_indicator.val); + compute_srs_resource_indicator(ul_bwp->pusch_servingcellconfig, pusch_Config, ul_bwp->srs_Config, srs_feedback, &dci_pdu_rel15->srs_resource_indicator.val); } compute_precoding_information(pusch_Config, ul_bwp->srs_Config, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index fa33d07536..921467c1bb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -2171,7 +2171,6 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) config_uldci(sib1, scc, - cg, pusch_pdu, &uldci_payload, &ps->srs_feedback, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 155a67f841..312e663e8d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -188,7 +188,6 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, void config_uldci(const NR_SIB1_t *sib1, const NR_ServingCellConfigCommon_t *scc, - const NR_CellGroupConfig_t *cg, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, nr_srs_feedback_t *srs_feedback, From 10faa7c55894d501b5c753507de68ce55446f804 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 13 Sep 2022 13:04:58 +0100 Subject: [PATCH 25/30] Fix phy-simulators build --- .../SIMULATION/NR_PHY/nr_dummy_functions.c | 76 +++++++++++++++---- openair1/SIMULATION/NR_PHY/pbchsim.c | 8 -- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index 75e3d998ff..ca9cf61115 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -5,25 +5,73 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { re int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } //int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } -int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); } -int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); } -int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); } -int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); } -int oai_nfapi_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) { return(0); } -int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind) { return(0); } -int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind) { return(0); } -int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind) { return(0); } -int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { return(0); } +int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) +{ + return (0); +} +int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req) +{ + return (0); +} +int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req) +{ + return (0); +} +int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req) +{ + return (0); +} +int oai_nfapi_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) +{ + return (0); +} +int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind) +{ + return (0); +} +int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind) +{ + return (0); +} +int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind) +{ + return (0); +} +int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) +{ + return (0); +} -int32_t get_uldl_offset(int nr_bandP) { return(0); } -NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);} +int pack_nr_srs_beamforming_report(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen) +{ + return 0; +} +int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen) +{ + return 0; +} + +int32_t get_uldl_offset(int nr_bandP) +{ + return (0); +} +NR_IF_Module_t *NR_IF_Module_init(int Mod_id) +{ + return (NULL); +} nfapi_mode_t nfapi_mod; -nfapi_mode_t nfapi_getmode(void) { +nfapi_mode_t nfapi_getmode(void) +{ return nfapi_mod; } -void nfapi_setmode(nfapi_mode_t nfapi_mode) {} +void nfapi_setmode(nfapi_mode_t nfapi_mode) +{ +} -int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); } +int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) +{ + return (0); +} int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, fapi_nr_dci_indication_t *dci_ind, diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index aa85f0f8e0..8c7bce71f6 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -108,14 +108,6 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, return false; } -int pack_nr_srs_beamforming_report(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen) { - return 0; -} - -int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen) { - return 0; -} - void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, int N_RB_DL, int N_RB_UL, From 4d97a47e8e529116926d6fc6042aecf3175afe14 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 19 Sep 2022 14:08:40 +0100 Subject: [PATCH 26/30] Add comment and break in get_pusch_nb_antenna_ports() function --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 1635187848..5d63f1be0e 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2717,10 +2717,14 @@ uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config, if(srs_config != NULL) { for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) { NR_SRS_ResourceSet_t *srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; - if(srs_resource_set->usage == NR_SRS_ResourceSet__usage_codebook) { + // When multiple SRS resources are configured by SRS-ResourceSet with usage set to 'codebook', + // the UE shall expect that higher layer parameters nrofSRS-Ports in SRS-Resource in SRS-ResourceSet + // shall be configured with the same value for all these SRS resources. + if (srs_resource_set->usage == NR_SRS_ResourceSet__usage_codebook) { NR_SRS_Resource_t *srs_resource = srs_config->srs_ResourceToAddModList->list.array[sri]; - AssertFatal(srs_resource != NULL,"SRS resource indicated by DCI does not exist\n"); - n_antenna_port = 1<nrofSRS_Ports; + AssertFatal(srs_resource != NULL, "SRS resource indicated by DCI does not exist\n"); + n_antenna_port = 1 << srs_resource->nrofSRS_Ports; + break; } } } From fd921eaf04426b97e7f6aa5557c9580366eb3e0e Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 19 Sep 2022 14:45:49 +0100 Subject: [PATCH 27/30] Remove nr_srs_feedback_t srs_feedback from NR_pusch_semi_static_t --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 53 +++++++++---------- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 6 ++- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 2c8224dfda..4aed63c628 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1188,14 +1188,17 @@ void handle_nr_srs_measurements(const module_id_t module_id, 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); - c16_t *channel_matrix16 = (c16_t*)nr_srs_normalized_channel_iq_matrix.channel_matrix; - c8_t *channel_matrix8 = (c8_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, + c16_t *channel_matrix16 = (c16_t *)nr_srs_normalized_channel_iq_matrix.channel_matrix; + c8_t *channel_matrix8 = (c8_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, nr_srs_normalized_channel_iq_matrix.normalized_iq_representation == 0 ? channel_matrix8[index].r : channel_matrix16[index].r, nr_srs_normalized_channel_iq_matrix.normalized_iq_representation == 0 ? channel_matrix8[index].i : channel_matrix16[index].i); } @@ -1206,19 +1209,18 @@ void handle_nr_srs_measurements(const module_id_t module_id, // TODO: This should be improved NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; - 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; // TODO: Compute this - ps->srs_feedback.tpmi = nr_srs_tpmi_estimation(current_BWP->pusch_Config, - current_BWP->transform_precoding, - nr_srs_normalized_channel_iq_matrix.channel_matrix, - nr_srs_normalized_channel_iq_matrix.normalized_iq_representation, - nr_srs_normalized_channel_iq_matrix.num_gnb_antenna_elements, - nr_srs_normalized_channel_iq_matrix.num_ue_srs_ports, - nr_srs_normalized_channel_iq_matrix.prg_size, - nr_srs_normalized_channel_iq_matrix.num_prgs, - ps->srs_feedback.ul_ri); - sprintf(stats->srs_stats,"UL-RI %d, TPMI %d", ps->srs_feedback.ul_ri+1, ps->srs_feedback.tpmi); + sched_ctrl->srs_feedback.sri = NR_SRS_SRI_0; + sched_ctrl->srs_feedback.ul_ri = 0; // TODO: Compute this + sched_ctrl->srs_feedback.tpmi = nr_srs_tpmi_estimation(current_BWP->pusch_Config, + current_BWP->transform_precoding, + nr_srs_normalized_channel_iq_matrix.channel_matrix, + nr_srs_normalized_channel_iq_matrix.normalized_iq_representation, + nr_srs_normalized_channel_iq_matrix.num_gnb_antenna_elements, + nr_srs_normalized_channel_iq_matrix.num_ue_srs_ports, + nr_srs_normalized_channel_iq_matrix.prg_size, + nr_srs_normalized_channel_iq_matrix.num_prgs, + sched_ctrl->srs_feedback.ul_ri); + sprintf(stats->srs_stats, "UL-RI %d, TPMI %d", sched_ctrl->srs_feedback.ul_ri + 1, sched_ctrl->srs_feedback.tpmi); break; } @@ -2266,14 +2268,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) dci_pdu_rel15_t uldci_payload; memset(&uldci_payload, 0, sizeof(uldci_payload)); - config_uldci(sib1, - scc, - pusch_pdu, - &uldci_payload, - &ps->srs_feedback, - ps->time_domain_allocation, - UE->UE_sched_ctrl.tpc0, - current_BWP); + config_uldci(sib1, scc, pusch_pdu, &uldci_payload, &sched_ctrl->srs_feedback, ps->time_domain_allocation, UE->UE_sched_ctrl.tpc0, current_BWP); fill_dci_pdu_rel15(scc, cg, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 2ab3208ab0..8501068f52 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -380,7 +380,6 @@ typedef struct NR_sched_pucch { typedef struct NR_pusch_semi_static_t { int time_domain_allocation; uint8_t nrOfLayers; - nr_srs_feedback_t srs_feedback; uint8_t num_dmrs_cdm_grps_no_data; int startSymbolIndex; int nrOfSymbols; @@ -650,7 +649,7 @@ typedef struct { NR_list_t feedback_ul_harq; /// UL HARQ processes that await retransmission NR_list_t retrans_ul_harq; - NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information + NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl; // MAC CE related information /// number of active DL LCs uint8_t dl_lc_num; /// order in which DLSCH scheduler should allocate LCs @@ -658,6 +657,9 @@ typedef struct { /// Timer for RRC processing procedures uint32_t rrc_processing_timer; + + /// sri, ul_ri and tpmi based on SRS + nr_srs_feedback_t srs_feedback; } NR_UE_sched_ctrl_t; typedef struct { From 9f23e202e057560677705dcee03cf89ced07cb5f Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Fri, 23 Sep 2022 11:13:40 +0100 Subject: [PATCH 28/30] Update documentation --- doc/FEATURE_SET.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 5db6e44d8d..fdd7435e9b 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -328,6 +328,7 @@ The following features are valid for the gNB and the 5G-NR UE. - HARQ procedures for uplink - Scheduler procedures for SRS reception - Periodic SRS reception + - TPMI computation based on SRS up 4 antenna ports and 1 layer - MAC procedures to handle CSI measurement report - evalution of RSRP report - evaluation of CQI report From 4156f895dd2c666b28daf5ecff89722b106c9dc0 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 27 Sep 2022 13:00:21 +0100 Subject: [PATCH 29/30] Set nrofSRS_Ports = min(maxNumberSRS_Ports, maxMIMO_Layers) --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 28 +++++++++++++++++------ openair2/RRC/NR/nr_rrc_config.c | 35 ++++++++++++++++++++++++----- openair2/RRC/NR/nr_rrc_config.h | 1 + openair2/RRC/NR/rrc_gNB_reconfig.c | 8 ++++++- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 47b6e38402..4c39caeb65 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1003,9 +1003,10 @@ void fill_initial_SpCellConfig(int uid, SpCellConfig->spCellConfigDedicated = calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated)); SpCellConfig->spCellConfigDedicated->uplinkConfig = calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->uplinkConfig)); + NR_UplinkConfig_t *uplinkConfig = SpCellConfig->spCellConfigDedicated->uplinkConfig; NR_BWP_UplinkDedicated_t *initialUplinkBWP = calloc(1,sizeof(*initialUplinkBWP)); - SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP = initialUplinkBWP; + uplinkConfig->initialUplinkBWP = initialUplinkBWP; initialUplinkBWP->pucch_Config = calloc(1,sizeof(*initialUplinkBWP->pucch_Config)); initialUplinkBWP->pucch_Config->present = NR_SetupRelease_PUCCH_Config_PR_setup; NR_PUCCH_Config_t *pucch_Config = calloc(1,sizeof(*pucch_Config)); @@ -1090,9 +1091,15 @@ void fill_initial_SpCellConfig(int uid, pusch_Config->uci_OnPUSCH=NULL; pusch_Config->tp_pi2BPSK=NULL; + long maxMIMO_Layers = uplinkConfig && + uplinkConfig->pusch_ServingCellConfig && + uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1 && + uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers ? + *uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers : 1; + // We are using do_srs = 0 here because the periodic SRS will only be enabled in update_cellGroupConfig() if do_srs == 1 initialUplinkBWP->srs_Config = calloc(1,sizeof(*initialUplinkBWP->srs_Config)); - config_srs(initialUplinkBWP->srs_Config, NULL, curr_bwp, uid, 0, 0); + config_srs(initialUplinkBWP->srs_Config, NULL, curr_bwp, uid, 0, maxMIMO_Layers, 0); scheduling_request_config(scc, pucch_Config); @@ -1216,7 +1223,7 @@ void fill_initial_SpCellConfig(int uid, n_ul_bwp = servingcellconfigdedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count; } if(n_ul_bwp>0) { - SpCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList = calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList)); + uplinkConfig->uplinkBWP_ToAddModList = calloc(1,sizeof(*uplinkConfig->uplinkBWP_ToAddModList)); for (int bwp_loop = 0; bwp_loop < n_ul_bwp; bwp_loop++) { NR_BWP_Uplink_t *ubwp = calloc(1, sizeof(*ubwp)); config_uplinkBWP(ubwp, bwp_loop, true, uid, @@ -1224,13 +1231,12 @@ void fill_initial_SpCellConfig(int uid, servingcellconfigdedicated, scc, NULL); - ASN_SEQUENCE_ADD(&SpCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list, ubwp); + ASN_SEQUENCE_ADD(&uplinkConfig->uplinkBWP_ToAddModList->list, ubwp); } - SpCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id)); - *SpCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = servingcellconfigdedicated->uplinkConfig->firstActiveUplinkBWP_Id ? *servingcellconfigdedicated->uplinkConfig->firstActiveUplinkBWP_Id : 1; + uplinkConfig->firstActiveUplinkBWP_Id = calloc(1,sizeof(*uplinkConfig->firstActiveUplinkBWP_Id)); + *uplinkConfig->firstActiveUplinkBWP_Id = uplinkConfig->firstActiveUplinkBWP_Id ? *uplinkConfig->firstActiveUplinkBWP_Id : 1; } - SpCellConfig->spCellConfigDedicated->csi_MeasConfig=calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->csi_MeasConfig)); SpCellConfig->spCellConfigDedicated->csi_MeasConfig->present = NR_SetupRelease_CSI_MeasConfig_PR_setup; @@ -1585,6 +1591,12 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, if(scc) { int curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); + NR_UplinkConfig_t *uplinkConfig = SpCellConfig && SpCellConfig->spCellConfigDedicated ? SpCellConfig->spCellConfigDedicated->uplinkConfig : NULL; + long maxMIMO_Layers = uplinkConfig && + uplinkConfig->pusch_ServingCellConfig && + uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1 && + uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers ? + *uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers : 1; // SRS configuration if (configuration->do_SRS && SpCellConfig && @@ -1600,6 +1612,7 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, curr_bwp, uid, 0, + maxMIMO_Layers, configuration->do_SRS); } @@ -1625,6 +1638,7 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, bwp_size, uid, i+1, + maxMIMO_Layers, configuration->do_SRS); } } diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 42077d7921..6764c6e28b 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -356,8 +356,9 @@ void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, const int curr_bwp, const int uid, const int res_id, - const int do_srs) { - + const long maxMIMO_Layers, + const int do_srs) +{ setup_release_srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup; NR_SRS_Config_t *srs_Config; @@ -420,6 +421,7 @@ void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, srs_res0->srs_ResourceId = res_id; srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1; if (do_srs) { + long nrofSRS_Ports = 1; if (uecap && uecap->featureSets && uecap->featureSets->featureSetsUplink && @@ -427,18 +429,33 @@ void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, NR_FeatureSetUplink_t *ul_feature_setup = uecap->featureSets->featureSetsUplink->list.array[0]; switch (ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource) { case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n1: - srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1; + nrofSRS_Ports = 1; break; case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n2: - srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports2; + nrofSRS_Ports = 2; break; case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n4: - srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports4; + nrofSRS_Ports = 4; break; default: LOG_E(NR_RRC, "Max Number of SRS Ports Per Resource %ld is invalid!\n", ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource); } + nrofSRS_Ports = min(nrofSRS_Ports, maxMIMO_Layers); + switch (nrofSRS_Ports) { + case 1: + srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1; + break; + case 2: + srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports2; + break; + case 4: + srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports4; + break; + default: + LOG_E(NR_RRC, "Number of SRS Ports Per Resource %ld is invalid!\n", + ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource); + } } LOG_I(NR_RRC, "SRS configured with %d ports\n", 1<nrofSRS_Ports); } @@ -1138,12 +1155,20 @@ void config_uplinkBWP(NR_BWP_Uplink_t *ubwp, pusch_Config->uci_OnPUSCH=NULL; pusch_Config->tp_pi2BPSK=NULL; + long maxMIMO_Layers = servingcellconfigdedicated && + servingcellconfigdedicated->uplinkConfig + && servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig + && servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1 + && servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers ? + *servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers : 1; + ubwp->bwp_Dedicated->srs_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->srs_Config)); config_srs(ubwp->bwp_Dedicated->srs_Config, NULL, curr_bwp, uid, bwp_loop+1, + maxMIMO_Layers, configuration->do_SRS); ubwp->bwp_Dedicated->configuredGrantConfig = NULL; diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index f8bdc4be53..27d6c5f080 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -150,6 +150,7 @@ void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, const int curr_bwp, const int uid, const int res_id, + const long maxMIMO_Layers, const int do_srs); void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap, diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 1dca25b618..9eb9d6366e 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -478,9 +478,15 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco LOG_I(RRC,"TRANSFORM PRECODING ENABLED......\n"); } + long maxMIMO_Layers = servingcellconfigdedicated->uplinkConfig && + servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig && + servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1 && + servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers ? + *servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers : 1; + int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); initialUplinkBWP->srs_Config = calloc(1,sizeof(*initialUplinkBWP->srs_Config)); - config_srs(initialUplinkBWP->srs_Config, NULL, curr_bwp, uid, 0, configuration->do_SRS); + config_srs(initialUplinkBWP->srs_Config, NULL, curr_bwp, uid, 0, maxMIMO_Layers, configuration->do_SRS); // Downlink BWPs int n_dl_bwp = 1; From fe1d7d93d8cf7a077de196f297f0ebcda454a508 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 27 Sep 2022 23:41:09 +0100 Subject: [PATCH 30/30] Fix bug in previous commit --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 4c39caeb65..48e5da8451 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1234,7 +1234,7 @@ void fill_initial_SpCellConfig(int uid, ASN_SEQUENCE_ADD(&uplinkConfig->uplinkBWP_ToAddModList->list, ubwp); } uplinkConfig->firstActiveUplinkBWP_Id = calloc(1,sizeof(*uplinkConfig->firstActiveUplinkBWP_Id)); - *uplinkConfig->firstActiveUplinkBWP_Id = uplinkConfig->firstActiveUplinkBWP_Id ? *uplinkConfig->firstActiveUplinkBWP_Id : 1; + *uplinkConfig->firstActiveUplinkBWP_Id = servingcellconfigdedicated->uplinkConfig->firstActiveUplinkBWP_Id ? *servingcellconfigdedicated->uplinkConfig->firstActiveUplinkBWP_Id : 1; } SpCellConfig->spCellConfigDedicated->csi_MeasConfig=calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->csi_MeasConfig));