Skip to content

Commit c4e91b0

Browse files
committed
phy: refactor pusch validator
1 parent ab3d759 commit c4e91b0

File tree

11 files changed

+87
-90
lines changed

11 files changed

+87
-90
lines changed

include/srsran/phy/upper/channel_processors/pusch/pusch_processor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#pragma once
1212

13+
#include "srsran/adt/expected.h"
1314
#include "srsran/adt/static_vector.h"
1415
#include "srsran/phy/support/re_pattern.h"
1516
#include "srsran/phy/upper/channel_coding/ldpc/ldpc.h"
@@ -184,7 +185,7 @@ class pusch_pdu_validator
184185

185186
/// \brief Validates PUSCH processor configuration parameters.
186187
/// \return True if the parameters contained in \c pdu are supported, false otherwise.
187-
virtual bool is_valid(const pusch_processor::pdu_t& pdu) const = 0;
188+
virtual error_type<std::string> is_valid(const pusch_processor::pdu_t& pdu) const = 0;
188189
};
189190

190191
} // namespace srsran

include/srsran/phy/upper/uplink_processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ class uplink_pdu_validator
162162

163163
/// \brief Validates PUSCH configuration parameters.
164164
/// \return True if the parameters contained in \c config are supported, false otherwise.
165-
virtual bool is_valid(const pusch_processor::pdu_t& config) const = 0;
165+
virtual error_type<std::string> is_valid(const pusch_processor::pdu_t& config) const = 0;
166166

167167
/// \brief Validates Sounding Reference Signals channel estimator configuration.
168168
/// \return True if the parameters contained in \c config are supported, false otherwise.

lib/fapi_adaptor/phy/fapi_to_phy_translator.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,11 @@ static expected<uplink_pdus> translate_ul_tti_pdus_to_phy_pdus(const fapi::ul_tt
439439
case fapi::ul_pdu_type::PUSCH: {
440440
uplink_processor::pusch_pdu& ul_pdu = pdus.pusch.emplace_back();
441441
convert_pusch_fapi_to_phy(ul_pdu, pdu.pusch_pdu, msg.sfn, msg.slot, carrier_cfg.num_rx_ant, part2_repo);
442-
if (!ul_pdu_validator.is_valid(ul_pdu.pdu)) {
443-
logger.warning("Upper PHY flagged a PUSCH PDU as having an invalid configuration. Skipping UL_TTI.request");
444-
442+
error_type<std::string> phy_pusch_validator = ul_pdu_validator.is_valid(ul_pdu.pdu);
443+
if (!phy_pusch_validator.has_value()) {
444+
logger.warning(
445+
"Skipping UL_TTI.request: PUSCH PDU flagged as invalid by the Upper PHY with the following error\n {}",
446+
phy_pusch_validator.error());
445447
return make_unexpected(default_error_t{});
446448
}
447449
break;

lib/phy/upper/channel_processors/pusch/factories.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ class pusch_processor_factory_generic : public pusch_processor_factory
238238
config.dec_nof_iterations = dec_nof_iterations;
239239
config.dec_enable_early_stop = dec_enable_early_stop;
240240
config.csi_sinr_calc_method = csi_sinr_calc_method;
241-
return std::make_unique<pusch_processor_impl>(config);
241+
return std::make_unique<pusch_processor_impl>(create_validator(), config);
242242
}
243243

244244
std::unique_ptr<pusch_pdu_validator> create_validator() override

lib/phy/upper/channel_processors/pusch/pusch_processor_impl.cpp

Lines changed: 15 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@
2323

2424
using namespace srsran;
2525

26+
/// Looks at the output of the validator and, if unsuccessful, fills msg with the error message.
27+
/// This is used to call the validator inside the process methods only if asserts are active.
28+
[[maybe_unused]] static bool handle_validation(std::string& msg, const error_type<std::string>& err)
29+
{
30+
bool is_success = err.has_value();
31+
if (!is_success) {
32+
msg = err.error();
33+
}
34+
return is_success;
35+
}
36+
2637
namespace {
2738
class pusch_processor_csi_part1_feedback_impl : public pusch_processor_csi_part1_feedback
2839
{
@@ -90,7 +101,8 @@ class pusch_processor_csi_part1_feedback_impl : public pusch_processor_csi_part1
90101
// Dummy PUSCH decoder buffer. Used for PUSCH transmissions without SCH data.
91102
static pusch_decoder_buffer_dummy decoder_buffer_dummy;
92103

93-
pusch_processor_impl::pusch_processor_impl(configuration& config) :
104+
pusch_processor_impl::pusch_processor_impl(std::unique_ptr<pusch_pdu_validator> pdu_validator_, configuration& config) :
105+
pdu_validator(std::move(pdu_validator_)),
94106
thread_local_dependencies_pool(std::move(config.thread_local_dependencies_pool)),
95107
decoder(std::move(config.decoder)),
96108
dec_nof_iterations(config.dec_nof_iterations),
@@ -117,7 +129,8 @@ void pusch_processor_impl::process(span<uint8_t> data,
117129
channel_estimate& ch_estimate = dependencies.get_channel_estimate();
118130

119131
// Assert PDU.
120-
assert_pdu(pdu, ch_estimate);
132+
[[maybe_unused]] std::string msg;
133+
srsran_assert(handle_validation(msg, pdu_validator->is_valid(pdu)), "{}", msg);
121134

122135
// Number of RB used by this transmission.
123136
unsigned nof_rb = pdu.freq_alloc.get_nof_rb();
@@ -306,49 +319,3 @@ void pusch_processor_impl::process(span<uint8_t> data,
306319
dependencies.get_demodulator().demodulate(
307320
demodulator_buffer, notifier_adaptor.get_demodulator_notifier(), grid, ch_estimate, demod_config);
308321
}
309-
310-
void pusch_processor_impl::assert_pdu(const pusch_processor::pdu_t& pdu, const channel_estimate& ch_estimate) const
311-
{
312-
using namespace units::literals;
313-
interval<unsigned, true> nof_tx_layers_range(1, ch_estimate.capacity().nof_tx_layers);
314-
315-
// Make sure the configuration is supported.
316-
srsran_assert((pdu.bwp_start_rb + pdu.bwp_size_rb) <= ch_estimate.capacity().nof_prb,
317-
"The sum of the BWP start (i.e., {}) and size (i.e., {}) exceeds the maximum grid size (i.e., {} PRB).",
318-
pdu.bwp_start_rb,
319-
pdu.bwp_size_rb,
320-
ch_estimate.capacity().nof_prb);
321-
if (std::holds_alternative<dmrs_configuration>(pdu.dmrs)) {
322-
const auto& dmrs = std::get<dmrs_configuration>(pdu.dmrs);
323-
srsran_assert(dmrs.dmrs == dmrs_type::TYPE1, "Only DM-RS Type 1 is currently supported.");
324-
srsran_assert(dmrs.nof_cdm_groups_without_data == 2, "Only two CDM groups without data are currently supported.");
325-
} else {
326-
srsran_assert(pdu.nof_tx_layers == 1, "Transform precoding is only possible with one layer.");
327-
srsran_assert(pdu.freq_alloc.is_contiguous(), "Transform precoding is only possible with contiguous allocations.");
328-
srsran_assert(is_transform_precoding_nof_prb_valid(pdu.freq_alloc.get_nof_rb()),
329-
"Transform precoding is only possible with a valid number of PRB.");
330-
}
331-
srsran_assert(nof_tx_layers_range.contains(pdu.nof_tx_layers),
332-
"The number of transmit layers (i.e., {}) is out of the range {}.",
333-
pdu.nof_tx_layers,
334-
nof_tx_layers_range);
335-
srsran_assert(pdu.rx_ports.size() <= ch_estimate.capacity().nof_rx_ports,
336-
"The number of receive ports (i.e., {}) exceeds the maximum number of receive ports (i.e., {}).",
337-
pdu.rx_ports.size(),
338-
ch_estimate.capacity().nof_rx_ports);
339-
340-
srsran_assert(pdu.uci.csi_part2_size.is_valid(pdu.uci.nof_csi_part1),
341-
"CSI Part 1 UCI field length (i.e., {}) does not correspond with the CSI Part 2 (i.e., {})",
342-
pdu.uci.nof_csi_part1,
343-
pdu.uci.csi_part2_size);
344-
srsran_assert(pdu.tbs_lbrm > 0_bytes, "Invalid LBRM size (0 bytes).");
345-
346-
// Check DC is whithin the CE.
347-
if (pdu.dc_position.has_value()) {
348-
interval<unsigned> dc_position_range(0, ch_estimate.size().nof_prb * NRE);
349-
srsran_assert(dc_position_range.contains(pdu.dc_position.value()),
350-
"DC position (i.e., {}) is out of range {}.",
351-
pdu.dc_position.value(),
352-
dc_position_range);
353-
}
354-
}

lib/phy/upper/channel_processors/pusch/pusch_processor_impl.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class pusch_processor_impl : public pusch_processor
108108

109109
/// \brief Constructs a generic software PUSCH processor.
110110
/// \param[in] config PUSCH processor dependencies and configuration parameters.
111-
pusch_processor_impl(configuration& config);
111+
pusch_processor_impl(std::unique_ptr<pusch_pdu_validator> pdu_validator_, configuration& config);
112112

113113
// See interface for documentation.
114114
void process(span<uint8_t> data,
@@ -118,9 +118,8 @@ class pusch_processor_impl : public pusch_processor
118118
const pdu_t& pdu) override;
119119

120120
private:
121-
/// Asserts the PDU. It triggers an assertion upon an invalid value or combination of values.
122-
void assert_pdu(const pusch_processor::pdu_t& pdu, const channel_estimate& ch_estimate) const;
123-
121+
/// PUSCH PDU validator.
122+
std::unique_ptr<pusch_pdu_validator> pdu_validator;
124123
/// Thread local dependencies pool.
125124
std::shared_ptr<concurrent_dependencies_pool_type> thread_local_dependencies_pool;
126125
/// UL-SCH transport block decoder.

lib/phy/upper/channel_processors/pusch/pusch_processor_validator_impl.cpp

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "pusch_processor_validator_impl.h"
1212
#include "pusch_processor_impl.h"
1313
#include "srsran/ran/transform_precoding/transform_precoding_helpers.h"
14+
#include "srsran/ran/uci/uci_formatters.h"
1415

1516
using namespace srsran;
1617

@@ -31,115 +32,137 @@ pusch_processor_validator_impl::pusch_processor_validator_impl(
3132
nof_tx_layers_range);
3233
}
3334

34-
bool pusch_processor_validator_impl::is_valid(const pusch_processor::pdu_t& pdu) const
35+
error_type<std::string> pusch_processor_validator_impl::is_valid(const pusch_processor::pdu_t& pdu) const
3536
{
3637
using namespace units::literals;
3738
unsigned nof_symbols_slot = get_nsymb_per_slot(pdu.cp);
3839

3940
// The BWP size exceeds the grid size.
4041
if ((pdu.bwp_start_rb + pdu.bwp_size_rb) > ce_dims.nof_prb) {
41-
return false;
42+
return make_unexpected(fmt::format(
43+
"The sum of the BWP start (i.e., {}) and size (i.e., {}) exceeds the maximum grid size (i.e., {} PRB).",
44+
pdu.bwp_start_rb,
45+
pdu.bwp_size_rb,
46+
ce_dims.nof_prb));
4247
}
4348

4449
// The implementation only works with a single transmit layer.
4550
if (pdu.nof_tx_layers > ce_dims.nof_tx_layers) {
46-
return false;
51+
return make_unexpected(fmt::format("The number of transmit layers (i.e., {}) is out of the range {}.",
52+
pdu.nof_tx_layers,
53+
interval<unsigned, true>(1, ce_dims.nof_tx_layers)));
4754
}
4855

4956
// The number of receive ports cannot exceed the maximum dimensions.
5057
if (pdu.rx_ports.size() > ce_dims.nof_rx_ports) {
51-
return false;
58+
return make_unexpected(
59+
fmt::format("The number of receive ports (i.e., {}) exceeds the maximum number of receive ports (i.e., {}).",
60+
pdu.rx_ports.size(),
61+
ce_dims.nof_rx_ports));
5262
}
5363

5464
// The frequency allocation is not compatible with the BWP parameters.
5565
if (!pdu.freq_alloc.is_bwp_valid(pdu.bwp_start_rb, pdu.bwp_size_rb)) {
56-
return false;
66+
return make_unexpected(fmt::format("Invalid BWP configuration {}:{}.", pdu.bwp_start_rb, pdu.bwp_size_rb));
5767
}
5868

5969
// Currently, none of the UCI field sizes can exceed 11 bit.
6070
static constexpr unsigned max_uci_len = 11;
6171
if ((pdu.uci.nof_harq_ack > max_uci_len) || (pdu.uci.nof_csi_part1 > max_uci_len)) {
62-
return false;
63-
}
64-
65-
// CSI Part 2 must not be present if CSI Part 1 is not present.
66-
if ((pdu.uci.nof_csi_part1 == 0) && !pdu.uci.csi_part2_size.entries.empty()) {
67-
return false;
72+
return make_unexpected(fmt::format("UCI field sizes in bits ({}, {}), exceed the maximum bit size, i.e., {}.",
73+
pdu.uci.nof_harq_ack,
74+
pdu.uci.nof_csi_part1,
75+
max_uci_len));
6876
}
6977

7078
// CSI Part 2 size parameters must be compatible with the CSI Part 1 number of bits.
7179
if (!pdu.uci.csi_part2_size.is_valid(pdu.uci.nof_csi_part1)) {
72-
return false;
80+
return make_unexpected(
81+
fmt::format("CSI Part 1 UCI field length (i.e., {}) does not correspond with the CSI Part 2 (i.e., {}).",
82+
pdu.uci.nof_csi_part1,
83+
pdu.uci.csi_part2_size));
7384
}
7485

7586
// The limited buffer for rate matching size must not be zero.
7687
if (pdu.tbs_lbrm == 0_bytes) {
77-
return false;
88+
return make_unexpected("Invalid LBRM size (0 bytes).");
7889
}
7990

8091
// The number of OFDM symbols in the DM-RS mask must be equal to the number of OFDM symbols in a slot.
8192
if (pdu.dmrs_symbol_mask.size() != nof_symbols_slot) {
82-
return false;
93+
return make_unexpected(fmt::format("The DM-RS symbol mask size (i.e., {}) must be the same as the number of "
94+
"symbols allocated to the transmission within the slot (i.e., {}).",
95+
pdu.dmrs_symbol_mask.size(),
96+
nof_symbols_slot));
8397
}
8498

8599
// The number of symbols carrying DM-RS must be greater than zero.
86100
if (pdu.dmrs_symbol_mask.none()) {
87-
return false;
101+
return make_unexpected("The number of OFDM symbols carrying DM-RS RE must be greater than zero.");
88102
}
89103

90104
// The index of the first OFDM symbol carrying DM-RS shall be equal to or greater than the first symbol allocated to
91105
// transmission.
92106
int first_dmrs_symbol_index = pdu.dmrs_symbol_mask.find_lowest(true);
93107
if (static_cast<unsigned>(first_dmrs_symbol_index) < pdu.start_symbol_index) {
94-
return false;
108+
return make_unexpected(fmt::format("The index of the first OFDM symbol carrying DM-RS (i.e., {}) must be equal to "
109+
"or greater than the first symbol allocated to transmission (i.e., {}).",
110+
first_dmrs_symbol_index,
111+
pdu.start_symbol_index));
95112
}
96113

97114
// The index of the last OFDM symbol carrying DM-RS shall not be larger than the last symbol allocated to
98115
// transmission.
99116
int last_dmrs_symbol_index = pdu.dmrs_symbol_mask.find_highest(true);
100117
if (static_cast<unsigned>(last_dmrs_symbol_index) >= (pdu.start_symbol_index + pdu.nof_symbols)) {
101-
return false;
118+
return make_unexpected(fmt::format("The index of the last OFDM symbol carrying DM-RS (i.e., {}) must be less than "
119+
"or equal to the last symbol allocated to transmission (i.e., {}).",
120+
last_dmrs_symbol_index,
121+
(pdu.start_symbol_index + pdu.nof_symbols - 1)));
102122
}
103123

104124
// None of the occupied symbols must exceed the slot size.
105125
if (nof_symbols_slot < (pdu.start_symbol_index + pdu.nof_symbols)) {
106-
return false;
126+
return make_unexpected(fmt::format("The occupied symbols (i.e., {}) exceed the slot size (i.e., {}).",
127+
pdu.start_symbol_index + pdu.nof_symbols,
128+
nof_symbols_slot));
107129
}
108130

109131
// Check if transform precoding is enabled.
110132
if (std::holds_alternative<pusch_processor::dmrs_configuration>(pdu.dmrs)) {
111-
const pusch_processor::dmrs_configuration& dmrs_config = std::get<pusch_processor::dmrs_configuration>(pdu.dmrs);
133+
const auto& dmrs_config = std::get<pusch_processor::dmrs_configuration>(pdu.dmrs);
112134
// Only DM-RS Type 1 is supported.
113135
if (dmrs_config.dmrs != dmrs_type::TYPE1) {
114-
return false;
136+
return make_unexpected("Only DM-RS Type 1 is currently supported.");
115137
}
116138

117139
// Only two CDM groups without data is supported.
118140
if (dmrs_config.nof_cdm_groups_without_data != 2) {
119-
return false;
141+
return make_unexpected("Only two CDM groups without data are currently supported.");
120142
}
121143
} else {
122144
// Number of layers must be one.
123145
if (pdu.nof_tx_layers != 1) {
124-
return false;
146+
return make_unexpected("Transform precoding is only possible with one layer.");
125147
}
126148

127149
// Frequency allocation must be contiguous.
128150
if (!pdu.freq_alloc.is_contiguous()) {
129-
return false;
151+
return make_unexpected("Transform precoding is only possible with contiguous allocations.");
130152
}
131153

132154
// Number of PRB must be valid.
133155
if (!is_transform_precoding_nof_prb_valid(pdu.freq_alloc.get_nof_rb())) {
134-
return false;
156+
return make_unexpected("Transform precoding is only possible with a valid number of PRB.");
135157
}
136158
}
137159

138160
// DC position is outside the channel estimate dimensions.
139161
interval<unsigned> dc_position_range(0, ce_dims.nof_prb * NRE);
140162
if (pdu.dc_position.has_value() && !dc_position_range.contains(pdu.dc_position.value())) {
141-
return false;
163+
return make_unexpected(
164+
fmt::format("DC position (i.e., {}) is out of range {}.", pdu.dc_position.value(), dc_position_range));
142165
}
143166

144-
return true;
167+
return default_success_t();
145168
}

lib/phy/upper/channel_processors/pusch/pusch_processor_validator_impl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010
#pragma once
1111

12+
#include "srsran/adt/expected.h"
1213
#include "srsran/phy/upper/channel_estimation.h"
1314
#include "srsran/phy/upper/channel_processors/pusch/pusch_processor.h"
1415

@@ -27,7 +28,7 @@ class pusch_processor_validator_impl : public pusch_pdu_validator
2728
explicit pusch_processor_validator_impl(const channel_estimate::channel_estimate_dimensions& ce_dims_);
2829

2930
// See interface for documentation.
30-
bool is_valid(const pusch_processor::pdu_t& pdu) const override;
31+
error_type<std::string> is_valid(const pusch_processor::pdu_t& pdu) const override;
3132

3233
private:
3334
channel_estimate::channel_estimate_dimensions ce_dims;

lib/phy/upper/upper_phy_pdu_validators.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ class uplink_processor_validator_impl : public uplink_pdu_validator
5555
{
5656
return pucch->is_valid(config);
5757
}
58-
bool is_valid(const pusch_processor::pdu_t& config) const override { return pusch->is_valid(config); }
58+
error_type<std::string> is_valid(const pusch_processor::pdu_t& config) const override
59+
{
60+
return pusch->is_valid(config);
61+
}
5962
bool is_valid(const srs_estimator_configuration& config) const override { return srs->is_valid(config); }
6063

6164
private:

tests/unittests/fapi_adaptor/phy/fapi_to_phy_translator_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ class uplink_pdu_validator_dummy : public uplink_pdu_validator
7979
{
8080
return default_success_t();
8181
}
82-
bool is_valid(const pusch_processor::pdu_t& pdu) const override { return true; }
83-
bool is_valid(const srs_estimator_configuration& config) const override { return true; }
82+
error_type<std::string> is_valid(const pusch_processor::pdu_t& pdu) const override { return default_success_t(); }
83+
bool is_valid(const srs_estimator_configuration& config) const override { return true; }
8484
};
8585

8686
class resource_grid_pool_dummy : public resource_grid_pool, private shared_resource_grid::pool_interface

0 commit comments

Comments
 (0)