Merge branch 'next' into agpl_next

This commit is contained in:
Codebot 2022-01-16 23:12:26 +01:00 committed by Your Name
commit 141073050e
10 changed files with 182 additions and 49 deletions

View File

@ -43,7 +43,7 @@ public:
*/
struct cell_search_result_t {
bool cell_found = false;
uint32_t pci = 0; ///< Physical Cell Identifier
uint32_t pci = 0; ///< Physical Cell Identifier
srsran_pbch_msg_nr_t pbch_msg; ///< Packed PBCH message for the upper layers
srsran_csi_trs_measurements_t measurements = {}; ///< Measurements from SSB block
};
@ -200,7 +200,7 @@ struct phy_args_nr_t {
srsran_ue_dl_nr_args_t dl = {};
srsran_ue_ul_nr_args_t ul = {};
std::set<uint32_t> fixed_sr = {1};
uint32_t fix_wideband_cqi = 15; // Set to a non-zero value for fixing the wide-band CQI report
uint32_t fix_wideband_cqi = 15; ///< Set to a non-zero value for fixing the wide-band CQI report
bool store_pdsch_ko = false;
float trs_epre_ema_alpha = 0.1f; ///< EPRE measurement exponential average alpha
float trs_rsrp_ema_alpha = 0.1f; ///< RSRP measurement exponential average alpha
@ -231,7 +231,6 @@ struct phy_args_nr_t {
class phy_interface_mac_nr
{
public:
// MAC informs PHY about UL grant included in RAR PDU
virtual int set_rar_grant(uint32_t rar_slot_idx,
std::array<uint8_t, SRSRAN_RAR_UL_GRANT_NBITS> packed_ul_grant,

View File

@ -63,6 +63,8 @@ private:
// {slot,cc} specific variables
slot_ue_map_t slot_ues;
slot_point last_tx_sl;
};
} // namespace sched_nr_impl

View File

@ -45,12 +45,18 @@ void cc_worker::dl_rach_info(const sched_nr_interface::rar_info_t& rar_info)
/// Called within a locked context, to generate {slot, cc} scheduling decision
dl_sched_res_t* cc_worker::run_slot(slot_point pdcch_slot, ue_map_t& ue_db)
dl_sched_res_t* cc_worker::run_slot(slot_point tx_sl, ue_map_t& ue_db)
{
// Reset old sched outputs
slot_point old_slot = pdcch_slot - TX_ENB_DELAY - 1;
for (bwp_manager& bwp : bwps) {
bwp.grid[old_slot].reset();
if (not last_tx_sl.valid()) {
last_tx_sl = tx_sl;
}
while (last_tx_sl != tx_sl) {
last_tx_sl++;
slot_point old_slot = last_tx_sl - TX_ENB_DELAY - 1;
for (bwp_manager& bwp : bwps) {
bwp.grid[old_slot].reset();
}
}
// Reserve UEs for this worker slot (select candidate UEs)
@ -62,7 +68,7 @@ dl_sched_res_t* cc_worker::run_slot(slot_point pdcch_slot, ue_map_t& ue_db)
}
// info for a given UE on a slot to be process
slot_ues.insert(rnti, u.make_slot_ue(pdcch_slot, cfg.cc));
slot_ues.insert(rnti, u.make_slot_ue(tx_sl, cfg.cc));
if (slot_ues[rnti].empty()) {
// Failed to generate slot UE because UE has no conditions for DL/UL tx
slot_ues.erase(rnti);
@ -72,10 +78,10 @@ dl_sched_res_t* cc_worker::run_slot(slot_point pdcch_slot, ue_map_t& ue_db)
}
// Create an BWP allocator object that will passed along to RA, SI, Data schedulers
bwp_slot_allocator bwp_alloc{bwps[0].grid, pdcch_slot, slot_ues};
bwp_slot_allocator bwp_alloc{bwps[0].grid, tx_sl, slot_ues};
// Log UEs state for slot
log_sched_slot_ues(logger, pdcch_slot, cfg.cc, slot_ues);
log_sched_slot_ues(logger, tx_sl, cfg.cc, slot_ues);
// Allocate cell DL signalling
sched_dl_signalling(bwp_alloc);

View File

@ -53,7 +53,7 @@ target_link_libraries(sched_nr_rar_test srsgnb_mac sched_nr_test_suite srsran_co
add_nr_test(sched_nr_rar_test sched_nr_rar_test)
add_executable(sched_nr_dci_utilities_tests sched_nr_dci_utilities_tests.cc)
target_link_libraries(sched_nr_dci_utilities_tests srsgnb_mac srsran_common srsran_phch)
target_link_libraries(sched_nr_dci_utilities_tests srsgnb_mac srsran_common)
add_nr_test(sched_nr_dci_utilities_tests sched_nr_dci_utilities_tests)
add_executable(sched_nr_test sched_nr_test.cc)

View File

@ -370,6 +370,16 @@ public:
uci_data.cfg.nof_csi = n;
}
// Set fix wideband CQI if it is not zero nor greater than 15
if (args.fix_wideband_cqi != 0 && args.fix_wideband_cqi < 15) {
for (uint32_t i = 0; i < uci_data.cfg.nof_csi; i++) {
if (uci_data.cfg.csi[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI &&
uci_data.cfg.csi[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND) {
uci_data.value.csi[i].wideband_cri_ri_pmi_cqi.cqi = args.fix_wideband_cqi;
}
}
}
uci_data.cfg.pucch.rnti = stack->get_ul_sched_rnti_nr(slot_cfg.idx).id;
}

View File

@ -151,6 +151,7 @@ private:
// helpers
void handle_sib1(const asn1::rrc_nr::sib1_s& sib1);
bool handle_rrc_setup(const asn1::rrc_nr::rrc_setup_s& setup);
void handle_rrc_reconfig(const asn1::rrc_nr::rrc_recfg_s& reconfig);
srsran::task_sched_handle task_sched;
struct cmd_msg_t {
@ -221,10 +222,12 @@ private:
std::map<uint32_t, srsran_csi_rs_nzp_resource_t> csi_rs_nzp_res;
bool apply_cell_group_cfg(const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg);
bool update_cell_group_cfg(const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg);
bool apply_radio_bearer_cfg(const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg);
bool apply_rlc_add_mod(const asn1::rrc_nr::rlc_bearer_cfg_s& rlc_bearer_cfg);
bool apply_mac_cell_group(const asn1::rrc_nr::mac_cell_group_cfg_s& mac_cell_group_cfg);
bool apply_sp_cell_cfg(const asn1::rrc_nr::sp_cell_cfg_s& sp_cell_cfg);
bool update_sp_cell_cfg(const asn1::rrc_nr::sp_cell_cfg_s& sp_cell_cfg);
bool apply_phy_cell_group_cfg(const asn1::rrc_nr::phys_cell_group_cfg_s& phys_cell_group_cfg);
bool apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_common);
bool apply_ul_common_cfg(const asn1::rrc_nr::ul_cfg_common_s& ul_cfg_common);

View File

@ -289,6 +289,20 @@ void rrc_nr::decode_dl_dcch(uint32_t lcid, unique_byte_buffer_t pdu)
return;
}
log_rrc_message(get_rb_name(lcid), Rx, pdu.get(), dl_dcch_msg, dl_dcch_msg.msg.c1().type().to_string());
dl_dcch_msg_type_c::c1_c_* c1 = &dl_dcch_msg.msg.c1();
switch (dl_dcch_msg.msg.c1().type().value) {
// TODO: ADD missing cases
case dl_dcch_msg_type_c::c1_c_::types::rrc_recfg: {
transaction_id = c1->rrc_recfg().rrc_transaction_id;
rrc_recfg_s recfg = c1->rrc_recfg();
task_sched.defer_task([this, recfg]() { handle_rrc_reconfig(recfg); });
break;
}
default:
logger.error("The provided DL-CCCH message type is not recognized or supported");
break;
}
}
void rrc_nr::write_pdu_bcch_bch(srsran::unique_byte_buffer_t pdu) {}
@ -824,8 +838,8 @@ int rrc_nr::get_nr_capabilities(srsran::byte_buffer_t* nr_caps_pdu)
void rrc_nr::phy_meas_stop()
{
// possbile race condition for sim_measurement timer, which might be set at the same moment as stopped => fix with
// phy integration
// possbile race condition for sim_measurement timer, which might be set at the same moment as stopped => fix
// with phy integration
logger.debug("Stopping simulated measurements");
sim_measurement_timer.stop();
}
@ -1564,6 +1578,15 @@ bool rrc_nr::apply_sp_cell_ded_ul_pusch(const asn1::rrc_nr::pusch_cfg_s& pusch_c
};
bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg)
{
update_sp_cell_cfg(sp_cell_cfg);
phy_cfg_state = PHY_CFG_STATE_APPLY_SP_CELL;
return true;
}
bool rrc_nr::update_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg)
{
srsran_csi_hl_cfg_t prev_csi = phy_cfg.csi;
if (sp_cell_cfg.recfg_with_sync_present) {
@ -1616,7 +1639,7 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg)
}
}
} else {
logger.warning("Reconfig with with sync not present");
logger.warning("Reconfig with sync not present");
}
// Dedicated config
@ -1735,8 +1758,6 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg)
current_phycfg.csi = prev_csi;
phy->set_config(current_phycfg);
phy_cfg_state = PHY_CFG_STATE_APPLY_SP_CELL;
return true;
}
@ -1753,6 +1774,15 @@ bool rrc_nr::apply_phy_cell_group_cfg(const phys_cell_group_cfg_s& phys_cell_gro
}
bool rrc_nr::apply_cell_group_cfg(const cell_group_cfg_s& cell_group_cfg)
{
update_cell_group_cfg(cell_group_cfg);
phy_cfg_state = PHY_CFG_STATE_APPLY_SP_CELL;
return true;
}
bool rrc_nr::update_cell_group_cfg(const cell_group_cfg_s& cell_group_cfg)
{
if (cell_group_cfg.rlc_bearer_to_add_mod_list_present) {
for (uint32_t i = 0; i < cell_group_cfg.rlc_bearer_to_add_mod_list.size(); i++) {
@ -1772,7 +1802,7 @@ bool rrc_nr::apply_cell_group_cfg(const cell_group_cfg_s& cell_group_cfg)
}
}
if (cell_group_cfg.sp_cell_cfg_present) {
if (apply_sp_cell_cfg(cell_group_cfg.sp_cell_cfg) == false) {
if (update_sp_cell_cfg(cell_group_cfg.sp_cell_cfg) == false) {
return false;
}
}
@ -1945,6 +1975,15 @@ bool rrc_nr::handle_rrc_setup(const rrc_setup_s& setup)
return true;
}
void rrc_nr::handle_rrc_reconfig(const rrc_recfg_s& reconfig)
{
if (not conn_recfg_proc.launch(nr, false, reconfig)) {
logger.error("Unable to launch connection reconfiguration procedure");
return;
}
callback_list.add_proc(conn_recfg_proc);
}
// RLC interface
void rrc_nr::max_retx_attempted() {}
void rrc_nr::protocol_failure() {}

View File

@ -43,49 +43,82 @@ proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::init(const reconf_initiator
Info("Starting...");
initiator = initiator_;
#if 0
asn1::json_writer js;
rrc_nr_reconf.to_json(js);
Debug("RRC NR Reconfiguration: %s", js.to_string().c_str());
#endif
if (rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group_present) {
if (rrc_nr_reconf.crit_exts.type() != asn1::rrc_nr::rrc_recfg_s::crit_exts_c_::types::rrc_recfg) {
Error("Reconfiguration does not contain Secondary Cell Group Config");
Error("Reconfiguration does not contain Secondary Cell Group Config.");
return proc_outcome_t::error;
}
cbit_ref bref0(rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group.data(),
rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group.size());
cell_group_cfg_s cell_group_cfg;
if (cell_group_cfg.unpack(bref0) != asn1::SRSASN_SUCCESS) {
Error("Could not unpack secondary cell group config.");
cell_group_cfg_s secondary_cell_group_cfg;
if (secondary_cell_group_cfg.unpack(bref0) != asn1::SRSASN_SUCCESS) {
Error("Could not unpack Secondary Cell Group Config.");
return proc_outcome_t::error;
}
#if 0
asn1::json_writer js1;
cell_group_cfg.to_json(js1);
secondary_cell_group_cfg.to_json(js1);
Debug("Secondary Cell Group: %s", js1.to_string().c_str());
#endif
Info("Applying Cell Group Cfg");
if (!rrc_handle.apply_cell_group_cfg(cell_group_cfg)) {
Info("Applying Secondary Cell Group Cfg.");
if (!rrc_handle.apply_cell_group_cfg(secondary_cell_group_cfg)) {
return proc_outcome_t::error;
}
}
if (rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext.sk_counter_present) {
Info("Applying sk counter");
Info("Applying SK Counter");
if (!rrc_handle.configure_sk_counter(
(uint16_t)rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext.sk_counter)) {
return proc_outcome_t::error;
}
}
if (rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.master_cell_group_present) {
cbit_ref bref1(rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.master_cell_group.data(),
rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.master_cell_group.size());
cell_group_cfg_s master_cell_group_cfg;
if (master_cell_group_cfg.unpack(bref1) != asn1::SRSASN_SUCCESS) {
Error("Could not unpack Master Cell Group Config.");
return proc_outcome_t::error;
}
asn1::json_writer js2;
master_cell_group_cfg.to_json(js2);
Debug("Master Cell Group: %s", js2.to_string().c_str());
Info("Applying Master Cell Group Cfg.");
if (!rrc_handle.apply_cell_group_cfg(master_cell_group_cfg)) {
return proc_outcome_t::error;
}
}
if (rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.ded_nas_msg_list_present) {
srsran::unique_byte_buffer_t nas_sdu;
for (uint32_t i = 0; i < rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.ded_nas_msg_list.size(); ++i) {
nas_sdu = srsran::make_byte_buffer();
if (nas_sdu != nullptr) {
memcpy(nas_sdu->msg,
rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.ded_nas_msg_list[i].data(),
rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.ded_nas_msg_list[i].size());
nas_sdu->N_bytes = rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.ded_nas_msg_list[i].size();
rrc_handle.write_sdu(std::move(nas_sdu));
} else {
rrc_handle.logger.error("Couldn't allocate SDU in %s.", __FUNCTION__);
return proc_outcome_t::error;
}
}
}
if (rrc_nr_reconf.crit_exts.rrc_recfg().radio_bearer_cfg_present) {
Info("Applying Radio Bearer Cfg");
Info("Applying Radio Bearer Cfg.");
if (!rrc_handle.apply_radio_bearer_cfg(rrc_nr_reconf.crit_exts.rrc_recfg().radio_bearer_cfg)) {
return proc_outcome_t::error;
}
@ -138,7 +171,7 @@ void rrc_nr::connection_reconf_no_ho_proc::then(const srsran::proc_state_t& resu
*************************************/
rrc_nr::setup_request_proc::setup_request_proc(rrc_nr& parent_) :
rrc_handle(parent_), logger(srslog::fetch_basic_logger("RRC"))
rrc_handle(parent_), logger(srslog::fetch_basic_logger("RRC-NR"))
{}
proc_outcome_t rrc_nr::setup_request_proc::init(srsran::nr_establishment_cause_t cause_,
@ -263,7 +296,7 @@ srsran::proc_outcome_t rrc_nr::setup_request_proc::react(const cell_selection_pr
// Simple procedure mainly do defer the transmission of the SetupComplete until all PHY reconfiguration are done
rrc_nr::connection_setup_proc::connection_setup_proc(srsue::rrc_nr& parent_) :
rrc_handle(parent_), logger(srslog::fetch_basic_logger("RRC"))
rrc_handle(parent_), logger(srslog::fetch_basic_logger("RRC-NR"))
{}
srsran::proc_outcome_t rrc_nr::connection_setup_proc::init(const asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg_,
@ -285,7 +318,7 @@ srsran::proc_outcome_t rrc_nr::connection_setup_proc::init(const asn1::rrc_nr::r
}
// Apply the Cell Group configuration
if (!rrc_handle.apply_cell_group_cfg(cell_group_)) {
if (!rrc_handle.update_cell_group_cfg(cell_group_)) {
return proc_outcome_t::error;
}

View File

@ -240,13 +240,7 @@ int rrc_nsa_reconfig_tdd_test()
asn1::rrc_nr::rrc_recfg_s secondary_cell_group_r15;
TESTASSERT(secondary_cell_group_r15.unpack(bref0) == asn1::SRSASN_SUCCESS);
TESTASSERT(secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group_present);
asn1::cbit_ref bref1(secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group.data(),
secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group.size());
asn1::rrc_nr::cell_group_cfg_s cell_group_cfg;
cell_group_cfg.unpack(bref1);
rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group_present = true;
rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group =
@ -346,13 +340,7 @@ int rrc_nsa_reconfig_fdd_test()
asn1::rrc_nr::rrc_recfg_s secondary_cell_group_r15;
TESTASSERT(secondary_cell_group_r15.unpack(bref0) == asn1::SRSASN_SUCCESS);
TESTASSERT(secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group_present);
asn1::cbit_ref bref1(secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group.data(),
secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group.size());
asn1::rrc_nr::cell_group_cfg_s cell_group_cfg;
TESTASSERT(cell_group_cfg.unpack(bref1) == asn1::SRSASN_SUCCESS);
rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group_present = true;
rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group =
@ -518,6 +506,57 @@ int rrc_nr_setup_test()
return SRSRAN_SUCCESS;
}
int rrc_nr_reconfig_test()
{
srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR");
logger.set_level(srslog::basic_levels::debug);
logger.set_hex_dump_max_size(-1);
srsran::task_scheduler task_sched{512, 100};
srsran::task_sched_handle task_sched_handle(&task_sched);
rrc_nr rrc_nr(task_sched_handle);
dummy_phy dummy_phy;
dummy_mac dummy_mac;
dummy_rlc dummy_rlc;
dummy_pdcp dummy_pdcp;
dummy_gw dummy_gw;
dummy_eutra dummy_eutra;
dummy_sim dummy_sim;
dummy_stack dummy_stack;
rrc_nr_args_t rrc_nr_args;
TESTASSERT(rrc_nr.init(&dummy_phy,
&dummy_mac,
&dummy_rlc,
&dummy_pdcp,
&dummy_gw,
&dummy_eutra,
&dummy_sim,
task_sched.get_timer_handler(),
&dummy_stack,
rrc_nr_args) == SRSRAN_SUCCESS);
uint8_t msg[] = {0x04, 0x8a, 0x80, 0x40, 0x9a, 0x01, 0xe0, 0x02, 0x05, 0xe1, 0xf0, 0x05, 0x00, 0x9a, 0x00, 0x15, 0x84,
0x88, 0x8b, 0xd7, 0x63, 0x80, 0x83, 0x2f, 0x00, 0x05, 0x8e, 0x03, 0xea, 0x41, 0xd0, 0x23, 0x00, 0x20,
0x25, 0x5f, 0x80, 0xa2, 0xef, 0x22, 0xc8, 0x40, 0xdf, 0x80, 0x1a, 0x00, 0x40, 0x21, 0x8b, 0x80, 0x40,
0x70, 0x84, 0xc0, 0x02, 0x40, 0x40, 0x01, 0x8c, 0x4c, 0x40, 0x40, 0x7f, 0xc0, 0x41, 0x82, 0xc0, 0x00,
0x42, 0xc0, 0x00, 0x4a, 0x43, 0x40, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x82, 0x8b, 0x40,
0x01, 0x88, 0x80, 0x40, 0x5e, 0x40, 0x01, 0x80, 0x48, 0x10, 0x40, 0x40, 0x42, 0x5e, 0xc0, 0x12, 0x20,
0x20, 0x08, 0x44, 0x00, 0x80, 0x00, 0x04, 0x20, 0x41, 0x82, 0x02, 0x02, 0x02, 0x20, 0xc1, 0x82, 0x02,
0x01, 0x01, 0x00, 0x00, 0xc4, 0x08, 0x00, 0x52, 0x18, 0x12, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0xc4, 0x08, 0x00, 0x52, 0x18, 0x12, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x22, 0x11, 0x00, 0x03, 0x41, 0x02, 0x02, 0x02, 0x02, 0x00, 0x03, 0x41, 0x02,
0x02, 0x01, 0x01, 0x09, 0x41, 0xc1, 0x9c, 0xdc, 0x9c, 0xd8, 0x5c, 0x1b, 0x84, 0x80, 0x40};
srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer();
memcpy(pdu->msg, msg, sizeof(msg));
pdu->N_bytes = sizeof(msg);
rrc_nr.write_pdu(1, std::move(pdu));
task_sched.run_pending_tasks();
return SRSRAN_SUCCESS;
}
int main(int argc, char** argv)
{
srslog::init();
@ -528,6 +567,7 @@ int main(int argc, char** argv)
TESTASSERT(rrc_nr_setup_request_test() == SRSRAN_SUCCESS);
TESTASSERT(rrc_nr_sib1_decoding_test() == SRSRAN_SUCCESS);
TESTASSERT(rrc_nr_setup_test() == SRSRAN_SUCCESS);
TESTASSERT(rrc_nr_reconfig_test() == SRSRAN_SUCCESS);
return SRSRAN_SUCCESS;
}

View File

@ -96,10 +96,11 @@ test_bench::args_t::args_t(int argc, char** argv)
;
options_ue_phy.add_options()
("ue.phy.nof_threads", bpo::value<uint32_t>(&ue_phy.nof_phy_threads)->default_value(1), "Number of threads")
("ue.phy.log.level", bpo::value<std::string>(&ue_phy.log.phy_level)->default_value("warning"), "UE PHY log level")
("ue.phy.log.hex_limit", bpo::value<int>(&ue_phy.log.phy_hex_limit)->default_value(0), "UE PHY log hex limit")
("ue.phy.log.id_preamble", bpo::value<std::string>(&ue_phy.log.id_preamble)->default_value(" UE/"), "UE PHY log ID preamble")
("ue.phy.fix_wideband_cqi", bpo::value<uint32_t>(&ue_phy.fix_wideband_cqi)->default_value(15), "Fix wideband CQI value, set to 0 or greater than 15 to disable")
("ue.phy.nof_threads", bpo::value<uint32_t>(&ue_phy.nof_phy_threads)->default_value(1), "Number of threads")
("ue.phy.log.level", bpo::value<std::string>(&ue_phy.log.phy_level)->default_value("warning"), "UE PHY log level")
("ue.phy.log.hex_limit", bpo::value<int>(&ue_phy.log.phy_hex_limit)->default_value(0), "UE PHY log hex limit")
("ue.phy.log.id_preamble", bpo::value<std::string>(&ue_phy.log.id_preamble)->default_value(" UE/"), "UE PHY log ID preamble")
;
options_ue_stack.add_options()