added scell parsing to the rr.conf

master
Francisco Paisana 5 years ago committed by Francisco Paisana
parent c8e50c1e19
commit 37a9501db3

@ -54,240 +54,249 @@ public:
class field_enum_str : public field_itf
{
public:
field_enum_str(const char* name_, T *store_ptr_, const char (*value_str_)[20], uint32_t nof_items_, bool *enabled_value_ = NULL)
field_enum_str(const char* name_,
T* store_ptr_,
const char (*value_str_)[20],
uint32_t nof_items_,
bool* enabled_value_ = NULL)
{
name = name_;
store_ptr = store_ptr_;
value_str = value_str_;
nof_items = nof_items_;
enabled_value = enabled_value_;
}
const char* get_name() {
return name;
name = name_;
store_ptr = store_ptr_;
value_str = value_str_;
nof_items = nof_items_;
enabled_value = enabled_value_;
}
int parse(Setting &root)
{
std::string val;
const char* get_name() { return name; }
int parse(Setting& root)
{
std::string val;
if (root.exists(name)) {
if (enabled_value) {
*enabled_value = true;
*enabled_value = true;
}
if (root.lookupValue(name, val)) {
bool found = false;
// find value
for (uint32_t i=0;i<nof_items && !found;i++) {
if (root.lookupValue(name, val)) {
bool found = false;
// find value
for (uint32_t i = 0; i < nof_items && !found; i++) {
if (!strcmp(value_str[i], val.c_str())) {
*store_ptr = (T) i;
found = true;
*store_ptr = (T)i;
found = true;
}
}
if (!found) {
fprintf(stderr, "Invalid option: %s for field %s\n", val.c_str(), name);
fprintf(stderr, "Valid options: %s", value_str[0]);
for (uint32_t i=1;i<nof_items;i++) {
for (uint32_t i = 1; i < nof_items; i++) {
fprintf(stderr, ", %s", value_str[i]);
}
fprintf(stderr, "\n");
return -1;
return -1;
}
return 0;
return 0;
} else {
return -1;
return -1;
}
} else {
if (enabled_value) {
*enabled_value = false;
return 0;
*enabled_value = false;
return 0;
} else {
return -1;
return -1;
}
}
}
private:
const char* name;
T *store_ptr;
const char (*value_str)[20];
uint32_t nof_items;
bool *enabled_value;
private:
const char* name;
T* store_ptr;
const char (*value_str)[20];
uint32_t nof_items;
bool* enabled_value;
};
template<class T, class S>
template <class T, class S>
class field_enum_num : public field_itf
{
public:
field_enum_num(const char* name_, T *store_ptr_, const S *value_str_, uint32_t nof_items_, bool *enabled_value_ = NULL)
field_enum_num(const char* name_,
T* store_ptr_,
const S* value_str_,
uint32_t nof_items_,
bool* enabled_value_ = NULL)
{
name = name_;
store_ptr = store_ptr_;
value_str = value_str_;
nof_items = nof_items_;
enabled_value = enabled_value_;
}
const char* get_name() {
return name;
name = name_;
store_ptr = store_ptr_;
value_str = value_str_;
nof_items = nof_items_;
enabled_value = enabled_value_;
}
int parse(Setting &root)
{
S val;
const char* get_name() { return name; }
int parse(Setting& root)
{
S val;
if (root.exists(name)) {
if (enabled_value) {
*enabled_value = true;
*enabled_value = true;
}
if (parser::lookupValue(root, name, &val)) {
bool found = false;
// find value
for (uint32_t i=0;i<nof_items && !found;i++) {
bool found = false;
// find value
for (uint32_t i = 0; i < nof_items && !found; i++) {
if (value_str[i] == val) {
*store_ptr = (T) i;
found = true;
*store_ptr = (T)i;
found = true;
}
}
if (!found) {
std::cout << "Invalid option: " << +val << " for field " << name << std::endl;
std::cout << "Valid options: ";
for (uint32_t i=0;i<nof_items;i++) {
std::cout << "Invalid option: " << +val << " for field " << name << std::endl;
std::cout << "Valid options: ";
for (uint32_t i = 0; i < nof_items; i++) {
std::cout << +value_str[i] << ", ";
}
std::cout << std::endl;
return -1;
return -1;
}
return 0;
return 0;
} else {
return -1;
return -1;
}
} else {
if (enabled_value) {
*enabled_value = false;
return 0;
*enabled_value = false;
return 0;
} else {
return -1;
return -1;
}
}
}
private:
const char* name;
T *store_ptr;
const S *value_str;
uint32_t nof_items;
bool *enabled_value;
private:
const char* name;
T* store_ptr;
const S* value_str;
uint32_t nof_items;
bool* enabled_value;
};
template<class T>
template <class T>
class field : public field_itf
{
public:
field(const char* name_, T *store_ptr_, bool *enabled_value_ = NULL)
field(const char* name_, T* store_ptr_, bool* enabled_value_ = NULL)
{
name = name_;
store_ptr = store_ptr_;
enabled_value = enabled_value_;
}
const char* get_name() {
return name;
name = name_;
store_ptr = store_ptr_;
enabled_value = enabled_value_;
}
int parse(Setting &root)
{
const char* get_name() { return name; }
int parse(Setting& root)
{
if (root.exists(name)) {
if (enabled_value) {
*enabled_value = true;
*enabled_value = true;
}
if (!parser::lookupValue(root, name, store_ptr)) {
return -1;
return -1;
} else {
return 0;
return 0;
}
} else {
if (enabled_value) {
*enabled_value = false;
return 0;
*enabled_value = false;
return 0;
} else {
return -1;
return -1;
}
}
}
private:
const char* name;
T *store_ptr;
bool *enabled_value;
private:
const char* name;
T* store_ptr;
bool* enabled_value;
};
class section
{
public:
public:
section(std::string name);
~section();
void set_optional(bool *enabled_value);
void add_subsection(section *s);
void add_field(field_itf *f);
int parse(Setting &root);
private:
std::string name;
bool *enabled_value;
std::list<section*> sub_sections;
std::list<field_itf*> fields;
};
void set_optional(bool* enabled_value);
void add_subsection(section* s);
void add_field(field_itf* f);
int parse(Setting& root);
private:
std::string name;
bool* enabled_value;
std::list<section*> sub_sections;
std::list<field_itf*> fields;
};
parser(std::string filename);
int parse();
void add_section(section *s);
static int parse_section(std::string filename, section *s);
static bool lookupValue(Setting &root, const char *name, std::string *val) {
return root.lookupValue(name, *val);
}
static bool lookupValue(Setting &root, const char *name, uint8_t *val) {
uint32_t t;
bool r = root.lookupValue(name, t);
*val = (uint8_t) t;
return r;
void add_section(section* s);
static int parse_section(std::string filename, section* s);
static bool lookupValue(Setting& root, const char* name, std::string* val) { return root.lookupValue(name, *val); }
static bool lookupValue(Setting& root, const char* name, uint8_t* val)
{
uint32_t t;
bool r = root.lookupValue(name, t);
*val = (uint8_t)t;
return r;
}
static bool lookupValue(Setting &root, const char *name, uint16_t *val) {
uint32_t t;
bool r = root.lookupValue(name, t);
*val = (uint16_t) t;
return r;
static bool lookupValue(Setting& root, const char* name, uint16_t* val)
{
uint32_t t;
bool r = root.lookupValue(name, t);
*val = (uint16_t)t;
return r;
}
static bool lookupValue(Setting &root, const char *name, uint32_t *val) {
uint32_t t;
bool r = root.lookupValue(name, t);
*val = t;
return r;
static bool lookupValue(Setting& root, const char* name, uint32_t* val)
{
uint32_t t;
bool r = root.lookupValue(name, t);
*val = t;
return r;
}
static bool lookupValue(Setting &root, const char *name, int8_t *val) {
int32_t t;
bool r = root.lookupValue(name, t);
*val = (int8_t) t;
return r;
static bool lookupValue(Setting& root, const char* name, int8_t* val)
{
int32_t t;
bool r = root.lookupValue(name, t);
*val = (int8_t)t;
return r;
}
static bool lookupValue(Setting &root, const char *name, int16_t *val) {
int32_t t;
bool r = root.lookupValue(name, t);
*val = (int16_t) t;
return r;
static bool lookupValue(Setting& root, const char* name, int16_t* val)
{
int32_t t;
bool r = root.lookupValue(name, t);
*val = (int16_t)t;
return r;
}
static bool lookupValue(Setting &root, const char *name, int32_t *val) {
int32_t t;
bool r = root.lookupValue(name, t);
*val = t;
return r;
static bool lookupValue(Setting& root, const char* name, int32_t* val)
{
int32_t t;
bool r = root.lookupValue(name, t);
*val = t;
return r;
}
static bool lookupValue(Setting &root, const char *name, double *val) {
double t;
bool r = root.lookupValue(name, t);
*val = t;
return r;
static bool lookupValue(Setting& root, const char* name, double* val)
{
double t;
bool r = root.lookupValue(name, t);
*val = t;
return r;
}
static bool lookupValue(Setting& root, const char* name, float* val)
{
@ -296,10 +305,11 @@ public:
*val = t;
return r;
}
static bool lookupValue(Setting &root, const char *name, bool *val) {
bool t;
static bool lookupValue(Setting& root, const char* name, bool* val)
{
bool t;
bool r = root.lookupValue(name, t);
*val = t;
*val = t;
return r;
}
@ -326,6 +336,18 @@ int parse_opt_field(T& obj, bool& flag, const char* field_name, Setting& root, P
return 0;
}
template <typename NumberType>
NumberType parse_bounded_number(Setting& fieldroot, NumberType num_min, NumberType num_max)
{
NumberType num = (NumberType)fieldroot;
if (num < num_min or num > num_max) {
std::cout << "Parser Warning: Value of " << fieldroot.getName() << " must be within bound [" << num_min << ", "
<< num_max << "]\n";
num = (num > num_max) ? num_max : num_min;
}
return num;
}
namespace asn1_parsers {
template <class EnumType>

@ -67,7 +67,7 @@ typedef struct {
asn1::rrc::rlc_cfg_c rlc_cfg;
} rrc_cfg_qci_t;
// structure used to parse the cfg file.
//! Cell to measure for HO. Filled by cfg file parser.
struct meas_cell_cfg_t {
uint32_t earfcn;
uint16_t pci;
@ -75,6 +75,13 @@ struct meas_cell_cfg_t {
float q_offset;
};
struct scell_cfg_t {
uint32_t cell_id;
bool cross_carrier_sched;
uint32_t sched_cell_id;
bool ul_allowed;
};
// neigh measurement Cell info
struct rrc_meas_cfg_t {
std::vector<meas_cell_cfg_t> meas_cells;
@ -86,6 +93,18 @@ struct rrc_meas_cfg_t {
// FIXME: Add multiple meas configs
};
// Cell/Sector configuration
struct cell_cfg_t {
uint32_t rf_port;
uint32_t cell_id;
uint32_t tac;
uint32_t pci;
uint32_t root_seq_idx;
uint32_t dl_earfcn;
uint32_t ul_earfcn;
std::vector<scell_cfg_t> scell_list;
};
#define MAX_NOF_QCI 10
struct rrc_cfg_t {
@ -106,6 +125,7 @@ struct rrc_cfg_t {
srslte::INTEGRITY_ALGORITHM_ID_ENUM eia_preference_list[srslte::INTEGRITY_ALGORITHM_ID_N_ITEMS];
bool meas_cfg_present = false;
rrc_meas_cfg_t meas_cfg;
std::vector<cell_cfg_t> cell_list;
uint32_t pci; // TODO: add this to srslte_cell_t?
uint32_t dl_earfcn; // TODO: add this to srslte_cell_t?
};

@ -33,17 +33,24 @@
} \
} while (0)
#define COND_PARSER_WARN(cond, msg_fmt, ...) \
do { \
if (cond) { \
printf(msg_fmt, ##__VA_ARGS__); \
} \
} while (0)
using namespace asn1::rrc;
namespace srsenb {
int enb::parse_cell_cfg(all_args_t* args, srslte_cell_t* cell)
int enb::parse_cell_cfg(all_args_t* args_, srslte_cell_t* cell)
{
cell->frame_type = SRSLTE_FDD;
cell->id = args->enb.pci;
cell->id = args_->enb.pci;
cell->cp = SRSLTE_CP_NORM;
cell->nof_ports = args->enb.nof_ports;
cell->nof_prb = args->enb.n_prb;
cell->nof_ports = args_->enb.nof_ports;
cell->nof_prb = args_->enb.n_prb;
phich_cfg_s phichcfg;
@ -52,13 +59,13 @@ int enb::parse_cell_cfg(all_args_t* args, srslte_cell_t* cell)
phy_cnfg.add_subsection(&phich_cnfg);
phich_cnfg.add_field(make_asn1_enum_str_parser("duration", &phichcfg.phich_dur));
phich_cnfg.add_field(make_asn1_enum_number_str_parser("resources", &phichcfg.phich_res));
parser::parse_section(args->enb_files.rr_config, &phy_cnfg);
parser::parse_section(args_->enb_files.rr_config, &phy_cnfg);
cell->phich_length = (srslte_phich_length_t)(int)phichcfg.phich_dur;
cell->phich_resources = (srslte_phich_r_t)(int)phichcfg.phich_res;
if (!srslte_cell_isvalid(cell)) {
fprintf(stderr, "Invalid cell parameters: nof_prb=%d, cell_id=%d\n", args->enb.n_prb, args->stack.s1ap.cell_id);
fprintf(stderr, "Invalid cell parameters: nof_prb=%d, cell_id=%d\n", args_->enb.n_prb, args_->stack.s1ap.cell_id);
return -1;
}
@ -243,7 +250,7 @@ int enb::parse_sib1(std::string filename, sib_type1_s* data)
sched_info.add_field(new field_sched_info(data));
// Run parser with single section
return parser::parse_section(filename, &sib1);
return parser::parse_section(std::move(filename), &sib1);
}
bool extract_sf_alloc(mbsfn_sf_cfg_s::sf_alloc_c_* store_ptr, const char* name, Setting& root)
@ -483,7 +490,7 @@ int enb::parse_sib2(std::string filename, sib_type2_s* data)
"format_2b", &rr_cfg_common->ul_pwr_ctrl_common.delta_flist_pucch.delta_f_pucch_format2b));
// Run parser with single section
return parser::parse_section(filename, &sib2);
return parser::parse_section(std::move(filename), &sib2);
}
int enb::parse_sib3(std::string filename, sib_type3_s* data)
@ -549,7 +556,7 @@ int enb::parse_sib3(std::string filename, sib_type3_s* data)
t_resel_eutra_sf.add_field(make_asn1_enum_number_str_parser("sf_high", &intrafreq->t_resel_eutra_sf.sf_high));
// Run parser with single section
return parser::parse_section(filename, &sib3);
return parser::parse_section(std::move(filename), &sib3);
}
int enb::parse_sib4(std::string filename, sib_type4_s* data)
@ -577,7 +584,7 @@ int enb::parse_sib4(std::string filename, sib_type4_s* data)
intra_black.add_field(new field_intra_black_cell_list(data));
// Run parser with single section
return parser::parse_section(filename, &sib4);
return parser::parse_section(std::move(filename), &sib4);
}
int enb::parse_sib7(std::string filename, sib_type7_s* data)
@ -595,7 +602,7 @@ int enb::parse_sib7(std::string filename, sib_type7_s* data)
geran_neigh.set_optional(&dummy_bool);
geran_neigh.add_field(new field_carrier_freqs_info_list(data));
return parser::parse_section(filename, &sib7);
return parser::parse_section(std::move(filename), &sib7);
}
int enb::parse_sib9(std::string filename, sib_type9_s* data)
@ -609,7 +616,7 @@ int enb::parse_sib9(std::string filename, sib_type9_s* data)
sib9.add_field(new parser::field<std::string>("hex_value", &hex_value, &hex_enabled));
// Run parser with single section
if (!parser::parse_section(filename, &sib9)) {
if (!parser::parse_section(std::move(filename), &sib9)) {
data->hnb_name_present = true;
if (name_enabled) {
data->hnb_name.resize(SRSLTE_MIN((uint32_t)hnb_name.size(), 48));
@ -646,9 +653,9 @@ int enb::parse_sib13(std::string filename, sib_type13_r9_s* data)
mbsfn_notification_config.add_field(
new parser::field<uint8>("mbsfn_notification_sf_index", &data->notif_cfg_r9.notif_sf_idx_r9));
sib13.add_field(new mbsfn_area_info_list_parser(&data->mbsfn_area_info_list_r9, NULL));
sib13.add_field(new mbsfn_area_info_list_parser(&data->mbsfn_area_info_list_r9, nullptr));
return parser::parse_section(filename, &sib13);
return parser::parse_section(std::move(filename), &sib13);
}
int mbsfn_area_info_list_parser::parse(Setting& root)
{
@ -722,34 +729,34 @@ int mbsfn_area_info_list_parser::parse(Setting& root)
return 0;
}
int enb::parse_sibs(all_args_t* args, rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_config_common)
int enb::parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_config_common)
{
// FIXME: Leave 0 blank for now
sib_type2_s* sib2 = &rrc_cfg->sibs[1].set_sib2();
sib_type3_s* sib3 = &rrc_cfg->sibs[2].set_sib3();
sib_type4_s* sib4 = &rrc_cfg->sibs[3].set_sib4();
sib_type7_s* sib7 = &rrc_cfg->sibs[6].set_sib7();
sib_type9_s* sib9 = &rrc_cfg->sibs[8].set_sib9();
sib_type13_r9_s* sib13 = &rrc_cfg->sibs[12].set_sib13_v920();
sib_type1_s* sib1 = &rrc_cfg->sib1;
if (parse_sib1(args->enb_files.sib_config, sib1)) {
sib_type2_s* sib2 = &rrc_cfg_->sibs[1].set_sib2();
sib_type3_s* sib3 = &rrc_cfg_->sibs[2].set_sib3();
sib_type4_s* sib4 = &rrc_cfg_->sibs[3].set_sib4();
sib_type7_s* sib7 = &rrc_cfg_->sibs[6].set_sib7();
sib_type9_s* sib9 = &rrc_cfg_->sibs[8].set_sib9();
sib_type13_r9_s* sib13 = &rrc_cfg_->sibs[12].set_sib13_v920();
sib_type1_s* sib1 = &rrc_cfg_->sib1;
if (parse_sib1(args_->enb_files.sib_config, sib1)) {
return -1;
}
// Fill rest of data from enb config
sib_type1_s::cell_access_related_info_s_* cell_access = &sib1->cell_access_related_info;
cell_access->cell_id.from_number((args->stack.s1ap.enb_id << 8u) + args->stack.s1ap.cell_id);
cell_access->tac.from_number(args->stack.s1ap.tac);
sib1->freq_band_ind = (uint8_t)srslte_band_get_band(args->enb.dl_earfcn);
cell_access->cell_id.from_number((args_->stack.s1ap.enb_id << 8u) + args_->stack.s1ap.cell_id);
cell_access->tac.from_number(args_->stack.s1ap.tac);
sib1->freq_band_ind = (uint8_t)srslte_band_get_band(args_->enb.dl_earfcn);
std::string mnc_str;
if (not srslte::mnc_to_string(args->stack.s1ap.mnc, &mnc_str)) {
ERROR("The provided mnc=%d is not valid", args->stack.s1ap.mnc);
if (not srslte::mnc_to_string(args_->stack.s1ap.mnc, &mnc_str)) {
ERROR("The provided mnc=%d is not valid", args_->stack.s1ap.mnc);
return -1;
}
std::string mcc_str;
if (not srslte::mcc_to_string(args->stack.s1ap.mcc, &mcc_str)) {
ERROR("The provided mnc=%d is not valid", args->stack.s1ap.mcc);
if (not srslte::mcc_to_string(args_->stack.s1ap.mcc, &mcc_str)) {
ERROR("The provided mnc=%d is not valid", args_->stack.s1ap.mcc);
return -1;
}
cell_access->plmn_id_list.resize(1);
@ -763,21 +770,21 @@ int enb::parse_sibs(all_args_t* args, rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_config_
sib1->cell_sel_info.q_rx_lev_min_offset = 0;
// Generate SIB2
if (parse_sib2(args->enb_files.sib_config, sib2)) {
if (parse_sib2(args_->enb_files.sib_config, sib2)) {
return -1;
}
// SRS not yet supported
sib2->rr_cfg_common.srs_ul_cfg_common.set(srs_ul_cfg_common_c::types::release);
if (sib2->freq_info.ul_bw_present) {
asn1::number_to_enum(sib2->freq_info.ul_bw, args->enb.n_prb);
asn1::number_to_enum(sib2->freq_info.ul_bw, args_->enb.n_prb);
}
if (sib2->freq_info.ul_carrier_freq_present) {
sib2->freq_info.ul_carrier_freq = (uint16_t)args->enb.ul_earfcn;
sib2->freq_info.ul_carrier_freq = (uint16_t)args_->enb.ul_earfcn;
}
// Update MBSFN list counter. Only 1 supported
if (not args->stack.embms.enable) {
if (not args_->stack.embms.enable) {
sib2->mbsfn_sf_cfg_list_present = false;
sib2->mbsfn_sf_cfg_list.resize(0);
} else {
@ -790,34 +797,34 @@ int enb::parse_sibs(all_args_t* args, rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_config_
// Generate SIB3 if defined in mapping info
if (sib_is_present(sib1->sched_info_list, sib_type_e::sib_type3)) {
if (parse_sib3(args->enb_files.sib_config, sib3)) {
if (parse_sib3(args_->enb_files.sib_config, sib3)) {
return -1;
}
}
// Generate SIB4 if defined in mapping info
if (sib_is_present(sib1->sched_info_list, sib_type_e::sib_type4)) {
if (parse_sib4(args->enb_files.sib_config, sib4)) {
if (parse_sib4(args_->enb_files.sib_config, sib4)) {
return -1;
}
}
// Generate SIB7 if defined in mapping info
if (sib_is_present(sib1->sched_info_list, sib_type_e::sib_type7)) {
if (parse_sib7(args->enb_files.sib_config, sib7)) {
if (parse_sib7(args_->enb_files.sib_config, sib7)) {
return -1;
}
}
// Generate SIB9 if defined in mapping info
if (sib_is_present(sib1->sched_info_list, sib_type_e::sib_type9)) {
if (parse_sib9(args->enb_files.sib_config, sib9)) {
if (parse_sib9(args_->enb_files.sib_config, sib9)) {
return -1;
}
}
if (sib_is_present(sib1->sched_info_list, sib_type_e::sib_type13_v920)) {
if (parse_sib13(args->enb_files.sib_config, sib13)) {
if (parse_sib13(args_->enb_files.sib_config, sib13)) {
return -1;
}
}
@ -845,55 +852,55 @@ bool enb::sib_is_present(const sched_info_list_l& l, sib_type_e sib_num)
return false;
}
int enb::parse_rr(all_args_t* args, rrc_cfg_t* rrc_cfg)
int enb::parse_rr(all_args_t* args_, rrc_cfg_t* rrc_cfg_)
{
/* Transmission mode config section */
if (args->enb.transmission_mode < 1 || args->enb.transmission_mode > 4) {
ERROR("Invalid transmission mode (%d). Only indexes 1-4 are implemented.\n", args->enb.transmission_mode);
if (args_->enb.transmission_mode < 1 || args_->enb.transmission_mode > 4) {
ERROR("Invalid transmission mode (%d). Only indexes 1-4 are implemented.\n", args_->enb.transmission_mode);
return SRSLTE_ERROR;
} else if (args->enb.transmission_mode == 1 && args->enb.nof_ports > 1) {
} else if (args_->enb.transmission_mode == 1 && args_->enb.nof_ports > 1) {
ERROR("Invalid number of ports (%d) for transmission mode (%d). Only one antenna port is allowed.\n",
args->enb.nof_ports,
args->enb.transmission_mode);
args_->enb.nof_ports,
args_->enb.transmission_mode);
return SRSLTE_ERROR;
} else if (args->enb.transmission_mode > 1 && args->enb.nof_ports != 2) {
} else if (args_->enb.transmission_mode > 1 && args_->enb.nof_ports != 2) {
ERROR("The selected number of ports (%d) are insufficient for the selected transmission mode (%d).\n",
args->enb.nof_ports,
args->enb.transmission_mode);
args_->enb.nof_ports,
args_->enb.transmission_mode);
return SRSLTE_ERROR;
}
rrc_cfg->antenna_info.tx_mode = (ant_info_ded_s::tx_mode_e_::options)(args->enb.transmission_mode - 1);
rrc_cfg_->antenna_info.tx_mode = (ant_info_ded_s::tx_mode_e_::options)(args_->enb.transmission_mode - 1);
rrc_cfg->antenna_info.ue_tx_ant_sel.set_setup();
switch (rrc_cfg->antenna_info.tx_mode) {
rrc_cfg_->antenna_info.ue_tx_ant_sel.set_setup();
switch (rrc_cfg_->antenna_info.tx_mode) {
case ant_info_ded_s::tx_mode_e_::tm1:
case ant_info_ded_s::tx_mode_e_::tm2:
rrc_cfg->antenna_info.ue_tx_ant_sel.set(setup_e::release);
rrc_cfg->antenna_info.codebook_subset_restrict_present = false;
rrc_cfg_->antenna_info.ue_tx_ant_sel.set(setup_e::release);
rrc_cfg_->antenna_info.codebook_subset_restrict_present = false;
break;
case ant_info_ded_s::tx_mode_e_::tm3:
rrc_cfg->antenna_info.ue_tx_ant_sel.setup().value = ant_info_ded_s::ue_tx_ant_sel_c_::setup_e_::open_loop;
rrc_cfg_->antenna_info.ue_tx_ant_sel.setup().value = ant_info_ded_s::ue_tx_ant_sel_c_::setup_e_::open_loop;
rrc_cfg->antenna_info.codebook_subset_restrict_present = true;
rrc_cfg->antenna_info.codebook_subset_restrict.set_n2_tx_ant_tm3();
rrc_cfg->antenna_info.codebook_subset_restrict.n2_tx_ant_tm3().from_number(0b11);
rrc_cfg_->antenna_info.codebook_subset_restrict_present = true;
rrc_cfg_->antenna_info.codebook_subset_restrict.set_n2_tx_ant_tm3();
rrc_cfg_->antenna_info.codebook_subset_restrict.n2_tx_ant_tm3().from_number(0b11);
break;
case ant_info_ded_s::tx_mode_e_::tm4:
rrc_cfg->antenna_info.ue_tx_ant_sel.setup().value = ant_info_ded_s::ue_tx_ant_sel_c_::setup_e_::closed_loop;
rrc_cfg_->antenna_info.ue_tx_ant_sel.setup().value = ant_info_ded_s::ue_tx_ant_sel_c_::setup_e_::closed_loop;
rrc_cfg->antenna_info.codebook_subset_restrict_present = true;
rrc_cfg->antenna_info.codebook_subset_restrict.set_n2_tx_ant_tm4();
rrc_cfg->antenna_info.codebook_subset_restrict.n2_tx_ant_tm4().from_number(0b111111);
rrc_cfg_->antenna_info.codebook_subset_restrict_present = true;
rrc_cfg_->antenna_info.codebook_subset_restrict.set_n2_tx_ant_tm4();
rrc_cfg_->antenna_info.codebook_subset_restrict.n2_tx_ant_tm4().from_number(0b111111);
break;
default:
ERROR("Unsupported transmission mode %d\n", rrc_cfg->antenna_info.tx_mode.to_number());
ERROR("Unsupported transmission mode %d\n", rrc_cfg_->antenna_info.tx_mode.to_number());
return SRSLTE_ERROR;
}
/* Parse power allocation */
if (not asn1::number_to_enum(rrc_cfg->pdsch_cfg, args->enb.p_a)) {
ERROR("Invalid p_a value (%f) only -6, -4.77, -3, -1.77, 0, 1, 2, 3 values allowed.", args->enb.p_a);
if (not asn1::number_to_enum(rrc_cfg_->pdsch_cfg, args_->enb.p_a)) {
ERROR("Invalid p_a value (%f) only -6, -4.77, -3, -1.77, 0, 1, 2, 3 values allowed.", args_->enb.p_a);
return SRSLTE_ERROR;
}
@ -901,62 +908,62 @@ int enb::parse_rr(all_args_t* args, rrc_cfg_t* rrc_cfg)
parser::section mac_cnfg("mac_cnfg");
parser::section phr_cnfg("phr_cnfg");
mac_cnfg.add_subsection(&phr_cnfg);
rrc_cfg->mac_cnfg.phr_cfg.set(
rrc_cfg_->mac_cnfg.phr_cfg.set(
mac_main_cfg_s::phr_cfg_c_::types::release); // default is release if "phr_cnfg" is not found
mac_cnfg.add_field(new phr_cnfg_parser(&rrc_cfg->mac_cnfg.phr_cfg));
// mac_cnfg.add_field(new phr_cnfg_parser(&rrc_cfg->mac_cnfg.phr_cfg));
mac_cnfg.add_field(new phr_cnfg_parser(&rrc_cfg_->mac_cnfg.phr_cfg));
// mac_cnfg.add_field(new phr_cnfg_parser(&rrc_cfg_->mac_cnfg.phr_cfg));
parser::section ulsch_cnfg("ulsch_cnfg");
mac_cnfg.add_subsection(&ulsch_cnfg);
rrc_cfg->mac_cnfg.ul_sch_cfg.tti_bundling = false;
rrc_cfg_->mac_cnfg.ul_sch_cfg.tti_bundling = false;
ulsch_cnfg.add_field(make_asn1_enum_number_parser(
"max_harq_tx", &rrc_cfg->mac_cnfg.ul_sch_cfg.max_harq_tx, &rrc_cfg->mac_cnfg.ul_sch_cfg.max_harq_tx_present));
"max_harq_tx", &rrc_cfg_->mac_cnfg.ul_sch_cfg.max_harq_tx, &rrc_cfg_->mac_cnfg.ul_sch_cfg.max_harq_tx_present));
ulsch_cnfg.add_field(make_asn1_enum_number_parser("periodic_bsr_timer",
&rrc_cfg->mac_cnfg.ul_sch_cfg.periodic_bsr_timer,
&rrc_cfg->mac_cnfg.ul_sch_cfg.periodic_bsr_timer_present));
ulsch_cnfg.add_field(make_asn1_enum_number_parser("retx_bsr_timer", &rrc_cfg->mac_cnfg.ul_sch_cfg.retx_bsr_timer));
&rrc_cfg_->mac_cnfg.ul_sch_cfg.periodic_bsr_timer,
&rrc_cfg_->mac_cnfg.ul_sch_cfg.periodic_bsr_timer_present));
ulsch_cnfg.add_field(make_asn1_enum_number_parser("retx_bsr_timer", &rrc_cfg_->mac_cnfg.ul_sch_cfg.retx_bsr_timer));
mac_cnfg.add_field(make_asn1_enum_number_parser("time_alignment_timer", &rrc_cfg->mac_cnfg.time_align_timer_ded));
mac_cnfg.add_field(make_asn1_enum_number_parser("time_alignment_timer", &rrc_cfg_->mac_cnfg.time_align_timer_ded));
/* PHY config section */
parser::section phy_cfg("phy_cnfg");
parser::section phy_cfg_("phy_cnfg");
parser::section pusch_cnfg_ded("pusch_cnfg_ded");
phy_cfg.add_subsection(&pusch_cnfg_ded);
phy_cfg_.add_subsection(&pusch_cnfg_ded);
pusch_cnfg_ded.add_field(new parser::field<uint8>("beta_offset_ack_idx", &rrc_cfg->pusch_cfg.beta_offset_ack_idx));
pusch_cnfg_ded.add_field(new parser::field<uint8>("beta_offset_ri_idx", &rrc_cfg->pusch_cfg.beta_offset_ri_idx));
pusch_cnfg_ded.add_field(new parser::field<uint8>("beta_offset_cqi_idx", &rrc_cfg->pusch_cfg.beta_offset_cqi_idx));
pusch_cnfg_ded.add_field(new parser::field<uint8>("beta_offset_ack_idx", &rrc_cfg_->pusch_cfg.beta_offset_ack_idx));
pusch_cnfg_ded.add_field(new parser::field<uint8>("beta_offset_ri_idx", &rrc_cfg_->pusch_cfg.beta_offset_ri_idx));
pusch_cnfg_ded.add_field(new parser::field<uint8>("beta_offset_cqi_idx", &rrc_cfg_->pusch_cfg.beta_offset_cqi_idx));
parser::section sched_request_cnfg("sched_request_cnfg");
phy_cfg.add_subsection(&sched_request_cnfg);
phy_cfg_.add_subsection(&sched_request_cnfg);
sched_request_cnfg.add_field(make_asn1_enum_number_parser("dsr_trans_max", &rrc_cfg->sr_cfg.dsr_max));
sched_request_cnfg.add_field(new parser::field<uint32>("period", &rrc_cfg->sr_cfg.period));
sched_request_cnfg.add_field(new parser::field<uint32>("nof_prb", &rrc_cfg->sr_cfg.nof_prb));
sched_request_cnfg.add_field(new field_sf_mapping(rrc_cfg->sr_cfg.sf_mapping, &rrc_cfg->sr_cfg.nof_subframes));
sched_request_cnfg.add_field(make_asn1_enum_number_parser("dsr_trans_max", &rrc_cfg_->sr_cfg.dsr_max));
sched_request_cnfg.add_field(new parser::field<uint32>("period", &rrc_cfg_->sr_cfg.period));
sched_request_cnfg.add_field(new parser::field<uint32>("nof_prb", &rrc_cfg_->sr_cfg.nof_prb));
sched_request_cnfg.add_field(new field_sf_mapping(rrc_cfg_->sr_cfg.sf_mapping, &rrc_cfg_->sr_cfg.nof_subframes));
parser::section cqi_report_cnfg("cqi_report_cnfg");
phy_cfg.add_subsection(&cqi_report_cnfg);
phy_cfg_.add_subsection(&cqi_report_cnfg);
cqi_report_cnfg.add_field(new parser::field_enum_str<rrc_cfg_cqi_mode_t>(
"mode", &rrc_cfg->cqi_cfg.mode, rrc_cfg_cqi_mode_text, RRC_CFG_CQI_MODE_N_ITEMS));
cqi_report_cnfg.add_field(new parser::field<uint32>("period", &rrc_cfg->cqi_cfg.period));
cqi_report_cnfg.add_field(new parser::field<uint32>("m_ri", &rrc_cfg->cqi_cfg.m_ri));
cqi_report_cnfg.add_field(new parser::field<uint32>("nof_prb", &rrc_cfg->cqi_cfg.nof_prb));
cqi_report_cnfg.add_field(new parser::field<bool>("simultaneousAckCQI", &rrc_cfg->cqi_cfg.simultaneousAckCQI));
cqi_report_cnfg.add_field(new field_sf_mapping(rrc_cfg->cqi_cfg.sf_mapping, &rrc_cfg->cqi_cfg.nof_subframes));
"mode", &rrc_cfg_->cqi_cfg.mode, rrc_cfg_cqi_mode_text, RRC_CFG_CQI_MODE_N_ITEMS));
cqi_report_cnfg.add_field(new parser::field<uint32>("period", &rrc_cfg_->cqi_cfg.period));
cqi_report_cnfg.add_field(new parser::field<uint32>("m_ri", &rrc_cfg_->cqi_cfg.m_ri));
cqi_report_cnfg.add_field(new parser::field<uint32>("nof_prb", &rrc_cfg_->cqi_cfg.nof_prb));
cqi_report_cnfg.add_field(new parser::field<bool>("simultaneousAckCQI", &rrc_cfg_->cqi_cfg.simultaneousAckCQI));
cqi_report_cnfg.add_field(new field_sf_mapping(rrc_cfg_->cqi_cfg.sf_mapping, &rrc_cfg_->cqi_cfg.nof_subframes));
/* RRC config section */
parser::section rrc_cnfg("rrc_cnfg");
rrc_cnfg.set_optional(&rrc_cfg->meas_cfg_present);
rrc_cnfg.add_field(new rr_sections::rrc_cnfg_section(&rrc_cfg->meas_cfg));
rrc_cnfg.set_optional(&rrc_cfg_->meas_cfg_present);
rrc_cnfg.add_field(new rr_sections::rrc_cnfg_section(args_, rrc_cfg_));
// Run parser with two sections
parser p(args->enb_files.rr_config);
parser p(args_->enb_files.rr_config);
p.add_section(&mac_cnfg);
p.add_section(&phy_cfg);
p.add_section(&phy_cfg_);
p.add_section(&rrc_cnfg);
return p.parse();
}
@ -991,16 +998,16 @@ int phr_cnfg_parser::parse(libconfig::Setting& root)
return 0;
}
int enb::parse_drb(all_args_t* args, rrc_cfg_t* rrc_cfg)
int enb::parse_drb(all_args_t* args_, rrc_cfg_t* rrc_cfg_)
{
parser::section qci("qci_config");
qci.add_field(new field_qci(rrc_cfg->qci_cfg));
return parser::parse_section(args->enb_files.drb_config, &qci);
qci.add_field(new field_qci(rrc_cfg_->qci_cfg));
return parser::parse_section(args_->enb_files.drb_config, &qci);
}
int field_qci::parse(libconfig::Setting& root)
{
uint32_t nof_qci = (uint32_t)root.getLength();
auto nof_qci = (uint32_t)root.getLength();
for (uint32_t i = 0; i < MAX_NOF_QCI; i++) {
cfg->configured = false;
@ -1025,11 +1032,8 @@ int field_qci::parse(libconfig::Setting& root)
"pdcp_sn_size", &cfg[qci].pdcp_cfg.rlc_um.pdcp_sn_size, &cfg[qci].pdcp_cfg.rlc_um_present);
pdcp_sn_size.parse(q["pdcp_config"]);
if (q["pdcp_config"].lookupValue("status_report_required", cfg[qci].pdcp_cfg.rlc_am.status_report_required)) {
cfg[qci].pdcp_cfg.rlc_am_present = true;
} else {
cfg[qci].pdcp_cfg.rlc_am_present = false;
}
cfg[qci].pdcp_cfg.rlc_am_present =
q["pdcp_config"].lookupValue("status_report_required", cfg[qci].pdcp_cfg.rlc_am.status_report_required);
cfg[qci].pdcp_cfg.hdr_compress.set(pdcp_cfg_s::hdr_compress_c_::types::not_used);
// Parse RLC section
@ -1149,13 +1153,8 @@ int field_qci::parse(libconfig::Setting& root)
}
parser::field<uint8> log_chan_group("log_chan_group", &lc_cfg->lc_ch_group);
if (log_chan_group.parse(q["logical_channel_config"])) {
lc_cfg->lc_ch_group_present = false;
} else {
lc_cfg->lc_ch_group_present = true;
}
cfg[qci].configured = true;
lc_cfg->lc_ch_group_present = not log_chan_group.parse(q["logical_channel_config"]);
cfg[qci].configured = true;
}
return 0;
@ -1204,13 +1203,46 @@ static int parse_meas_report_desc(rrc_meas_cfg_t* meas_cfg, Setting& root)
HANDLEPARSERCODE(
asn1_parsers::opt_number_to_enum(quant.filt_coef_rsrq, quant.filt_coef_rsrq_present, root, "rsrq_config"));
return 0;
return SRSLTE_SUCCESS;
}
static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root)
{
rrc_cfg->cell_list.resize(root.getLength());
for (uint32_t n = 0; n < rrc_cfg->cell_list.size(); ++n) {
cell_cfg_t& cell_cfg = rrc_cfg->cell_list[n];
cell_cfg.rf_port = (uint32_t)root[n]["rf_port"];
cell_cfg.cell_id = parse_bounded_number<uint32_t>(root[n]["cell_id"], 0, 255);
cell_cfg.tac = (uint32_t)root[n]["tac"];
cell_cfg.pci = (uint32_t)root[n]["pci"];
cell_cfg.root_seq_idx = (uint32_t)root[n]["root_seq_idx"];
if (not root[n].lookupValue("dl_earfcn", cell_cfg.dl_earfcn)) {
cell_cfg.dl_earfcn = args->enb.dl_earfcn; // default to enb.conf
}
if (not root[n].lookupValue("ul_earfcn", cell_cfg.ul_earfcn)) {
cell_cfg.ul_earfcn = args->enb.ul_earfcn;
}
cell_cfg.scell_list.resize(root["scell_list"].getLength());
for (uint32_t i = 0; i < cell_cfg.scell_list.size(); ++i) {
auto& scell = cell_cfg.scell_list[i];
auto& scellroot = root["scell_list"][i];
scell.cell_id = parse_bounded_number<uint32_t>(scellroot["cell_id"], 0, 255);
scell.cross_carrier_sched = (bool)scellroot["cross_carrier_scheduling"];
scell.sched_cell_id = parse_bounded_number<uint32_t>(scellroot["scheduling_cell_id"], 0, 255);
scell.ul_allowed = (bool)scellroot["ul_allowed"];
}
}
return SRSLTE_SUCCESS;
}
int rrc_cnfg_section::parse(libconfig::Setting& root)
{
HANDLEPARSERCODE(parse_meas_cell_list(meas_cfg, root["meas_cell_list"]));
HANDLEPARSERCODE(parse_meas_report_desc(meas_cfg, root["meas_report_desc"]));
HANDLEPARSERCODE(parse_meas_cell_list(&rrc_cfg->meas_cfg, root["meas_cell_list"]));
HANDLEPARSERCODE(parse_meas_report_desc(&rrc_cfg->meas_cfg, root["meas_report_desc"]));
HANDLEPARSERCODE(parse_cell_list(args, rrc_cfg, root["cell_list"]));
return 0;
}

@ -37,6 +37,8 @@ namespace srsenb {
using namespace libconfig;
class all_args_t;
class field_sched_info final : public parser::field_itf
{
public:
@ -97,7 +99,7 @@ private:
uint32_t* nof_subframes;
};
class field_qci : public parser::field_itf
class field_qci final : public parser::field_itf
{
public:
explicit field_qci(rrc_cfg_qci_t* cfg_) { cfg = cfg_; }
@ -116,14 +118,15 @@ namespace rr_sections {
class rrc_cnfg_section final : public parser::field_itf
{
public:
explicit rrc_cnfg_section(rrc_meas_cfg_t* meas_cfg_) : meas_cfg(meas_cfg_) {}
explicit rrc_cnfg_section(all_args_t* all_args_, rrc_cfg_t* rrc_cfg_) : args(all_args_), rrc_cfg(rrc_cfg_) {}
int parse(Setting& root) override;
const char* get_name() override { return "meas_cell_list"; }
private:
rrc_meas_cfg_t* meas_cfg;
rrc_cfg_t* rrc_cfg;
all_args_t* args;
};
} // namespace rr_sections
@ -502,7 +505,6 @@ class phr_cnfg_parser : public parser::field_itf
{
public:
explicit phr_cnfg_parser(asn1::rrc::mac_main_cfg_s::phr_cfg_c_* phr_cfg_) { phr_cfg = phr_cfg_; }
~phr_cnfg_parser() override = default;
int parse(Setting& root) override;
const char* get_name() override { return "phr_cnfg"; }
@ -518,7 +520,6 @@ public:
enabled(enabled_)
{
}
~mbsfn_sf_cfg_list_parser() override = default;
int parse(Setting& root) override;
const char* get_name() override { return "mbsfnSubframeConfigList"; }
@ -535,7 +536,6 @@ public:
enabled(enabled_)
{
}
~mbsfn_area_info_list_parser() override = default;
int parse(Setting& root) override;
const char* get_name() override { return "mbsfn_area_info_list"; }

@ -26,16 +26,16 @@ namespace srsenb {
using namespace libconfig;
int parser::parse_section(std::string filename, parser::section *s)
int parser::parse_section(std::string filename, parser::section* s)
{
parser p(filename);
p.add_section(s);
return p.parse();
}
parser::parser(std::string filename_)
{
filename = filename_;
filename = filename_;
}
void parser::add_section(parser::section* s)
@ -45,45 +45,38 @@ void parser::add_section(parser::section* s)
int parser::parse()
{
// open file
// open file
Config cfg;
try
{
try {
cfg.readFile(filename.c_str());
}
catch(const FileIOException &fioex)
{
} catch (const FileIOException& fioex) {
std::cerr << "I/O error while reading file: " << filename << std::endl;
return(-1);
}
catch(const ParseException &pex)
{
std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
<< " - " << pex.getError() << std::endl;
return(-1);
return (-1);
} catch (const ParseException& pex) {
std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine() << " - " << pex.getError() << std::endl;
return (-1);
}
for (std::list<section*>::iterator ci = sections.begin(); ci != sections.end(); ++ci) {
section *s = *ci;
for (auto s : sections) {
if (s->parse(cfg.getRoot())) {
return -1;
return -1;
}
}
return 0;
return 0;
}
parser::section::section(std::string name_)
{
name = name_;
enabled_value = NULL;
name = std::move(name_);
enabled_value = nullptr;
}
// Fields are allocated dynamically, free all fields added to the section
parser::section::~section()
parser::section::~section()
{
for (std::list<field_itf*>::iterator ci = fields.begin(); ci != fields.end(); ++ci) {
delete *ci;
for (auto& field : fields) {
delete field;
}
}
@ -99,43 +92,37 @@ void parser::section::add_subsection(parser::section* s)
void parser::section::set_optional(bool* enabled_value_)
{
enabled_value = enabled_value_;
enabled_value = enabled_value_;
}
int parser::section::parse(Setting &root)
int parser::section::parse(Setting& root)
{
try {
for (std::list<field_itf*>::iterator ci = fields.begin(); ci != fields.end(); ++ci) {
field_itf *f = *ci;
for (auto f : fields) {
if (f->parse(root[name.c_str()])) {
fprintf(stderr, "Error parsing field %s in section %s\n", f->get_name(), name.c_str());
return -1;
return -1;
}
}
for (std::list<section*>::iterator ci = sub_sections.begin(); ci != sub_sections.end(); ++ci) {
section *s = *ci;
for (auto s : sub_sections) {
if (s->parse(root[name.c_str()])) {
fprintf(stderr, "Error parsing section %s\n", name.c_str());
return -1;
return -1;
}
}
if (enabled_value) {
*enabled_value = true;
*enabled_value = true;
}
} catch (const SettingNotFoundException& ex) {
if (enabled_value) {
*enabled_value = false;
return 0;
*enabled_value = false;
return 0;
} else {
std::cerr << "Error section " << name.c_str() << " not found." << std::endl;
return -1;
}
}
return 0;
return 0;
}
}
} // namespace srsenb

Loading…
Cancel
Save