@@ -56,7 +56,7 @@ struct nr_band_raster {
5656// NOTE: FR2 bands have two different Freq raster, we only consider raster 120kHz.
5757const uint32_t nof_nr_DL_bands = 83 ;
5858static constexpr std::array<nr_band_raster, nof_nr_DL_bands> nr_band_table = {{
59- // clang-format off
59+ // clang-format off
6060 {nr_band::n1, delta_freq_raster::kHz100 , 384000 , 20 , 396000 , 422000 , 20 , 434000 },
6161 {nr_band::n2, delta_freq_raster::kHz100 , 370000 , 20 , 382000 , 386000 , 20 , 398000 },
6262 {nr_band::n3, delta_freq_raster::kHz100 , 342000 , 20 , 357000 , 361000 , 20 , 376000 },
@@ -150,7 +150,7 @@ struct nr_operating_band {
150150};
151151static const uint32_t nof_nr_operating_band = 68 ;
152152static constexpr std::array<nr_operating_band, nof_nr_operating_band> nr_operating_bands = {{
153- // clang-format off
153+ // clang-format off
154154 {nr_band::n1, duplex_mode::FDD},
155155 {nr_band::n2, duplex_mode::FDD},
156156 {nr_band::n3, duplex_mode::FDD},
@@ -456,30 +456,33 @@ static bool is_valid_raster_param(const nr_raster_params& raster)
456456
457457// Validates band n28, which has an additional ARFCN value to the given interval, as per Table 5.4.2.3-1, TS 38.104,
458458// version 17.8.0.
459- static error_type<std::string> validate_band_n28 (uint32_t arfcn, bs_channel_bandwidth bw)
459+ static error_type<std::string> validate_band_n28 (uint32_t arfcn, bs_channel_bandwidth bw, bool is_dl = true )
460460{
461461 const nr_band_raster band_raster = fetch_band_raster (nr_band::n28, {});
462462 if (band_raster.band == srsran::nr_band::invalid) {
463463 return make_unexpected (fmt::format (" Band n28 channel raster not found" ));
464464 }
465465
466466 // Try first if the ARFCN matches any value of the interval for 100kHz channel raster.
467- if (arfcn >= band_raster.dl_nref_first and arfcn <= band_raster.dl_nref_last and
468- ((arfcn - band_raster.dl_nref_first ) % band_raster.dl_nref_step ) == 0 ) {
467+ uint32_t nref_first = is_dl ? band_raster.dl_nref_first : band_raster.ul_nref_first ;
468+ uint32_t nref_last = is_dl ? band_raster.dl_nref_last : band_raster.ul_nref_last ;
469+ uint32_t nref_step = is_dl ? band_raster.dl_nref_step : band_raster.ul_nref_step ;
470+ if (arfcn >= nref_first and arfcn <= nref_last and ((arfcn - nref_first) % nref_step) == 0 ) {
469471 return error_type<std::string>{};
470472 }
471473
472474 // Extra ARFCN value as per Table 5.4.2.3-1, TS 38.104, version 17.8.0 (see NOTE 4 in the table).
473- const uint32_t dl_arfnc_40MHz = 155608U ;
474- if (bw == srsran::bs_channel_bandwidth::MHz40 and arfcn == dl_arfnc_40MHz ) {
475+ const uint32_t arfnc_40MHz = is_dl ? 155608U : 144608U ;
476+ if (bw == srsran::bs_channel_bandwidth::MHz40 and arfcn == arfnc_40MHz ) {
475477 return error_type<std::string>{};
476478 }
477479
478480 return make_unexpected (
479- fmt::format (" DL ARFCN must be within the interval [{},{}], in steps of {}, for the chosen band" ,
480- band_raster.dl_nref_first ,
481- band_raster.dl_nref_last ,
482- band_raster.dl_nref_step ));
481+ fmt::format (" {} ARFCN must be within the interval [{},{}], in steps of {}, for the chosen band" ,
482+ is_dl ? " DL" : " UL" ,
483+ nref_first,
484+ nref_last,
485+ nref_step));
483486}
484487
485488// Validates band n46, whose valid ARFCN values depend on the channel BW, as per Table 5.4.2.3-1, TS 38.104,
@@ -743,7 +746,7 @@ error_type<std::string> srsran::band_helper::is_dl_arfcn_valid_given_band(nr_ban
743746{
744747 // Validates first the bands with non-standard ARFCN values.
745748 if (band == nr_band::n28) {
746- return validate_band_n28 (arfcn_f_ref, bw);
749+ return validate_band_n28 (arfcn_f_ref, bw, true );
747750 }
748751
749752 if (band == nr_band::n46) {
@@ -796,6 +799,37 @@ error_type<std::string> srsran::band_helper::is_dl_arfcn_valid_given_band(nr_ban
796799 return make_unexpected (fmt::format (" Band {} is not valid" , band));
797800}
798801
802+ error_type<std::string>
803+ srsran::band_helper::is_ul_arfcn_valid_given_band (nr_band band, uint32_t arfcn_f_ref, bs_channel_bandwidth bw)
804+ {
805+ if (get_duplex_mode (band) != duplex_mode::FDD) {
806+ return {};
807+ }
808+
809+ // Validates first the bands with non-standard ARFCN values.
810+ if (band == nr_band::n28) {
811+ return validate_band_n28 (arfcn_f_ref, bw, false );
812+ }
813+
814+ // Assume standard Delta freq raster of 100kHz.
815+ const delta_freq_raster band_delta_freq_raster = delta_freq_raster::kHz100 ;
816+
817+ for (const nr_band_raster& raster_band : nr_band_table) {
818+ if (raster_band.band == band and raster_band.delta_f_rast == band_delta_freq_raster) {
819+ if (arfcn_f_ref >= raster_band.ul_nref_first and arfcn_f_ref <= raster_band.ul_nref_last and
820+ ((arfcn_f_ref - raster_band.ul_nref_first ) % raster_band.ul_nref_step ) == 0 ) {
821+ return {};
822+ }
823+ return make_unexpected (
824+ fmt::format (" UL ARFCN must be within the interval [{},{}], in steps of {}, for the chosen band" ,
825+ raster_band.ul_nref_first ,
826+ raster_band.ul_nref_last ,
827+ raster_band.ul_nref_step ));
828+ }
829+ }
830+ return make_unexpected (fmt::format (" Band {} is not valid" , band));
831+ }
832+
799833uint32_t srsran::band_helper::get_ul_arfcn_from_dl_arfcn (uint32_t dl_arfcn, std::optional<nr_band> band)
800834{
801835 // NOTE: The procedure implemented in this function is implementation-defined.
0 commit comments