diff --git a/lib/include/srslte/interfaces/enb_interfaces.h b/lib/include/srslte/interfaces/enb_interfaces.h index 8bd43f27a..2c80229b4 100644 --- a/lib/include/srslte/interfaces/enb_interfaces.h +++ b/lib/include/srslte/interfaces/enb_interfaces.h @@ -296,8 +296,8 @@ public: * Segmentation happens in this function. RLC PDU is stored in payload. */ virtual int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) = 0; - virtual void read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t* payload) = 0; - virtual void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) = 0; + virtual void read_pdu_bcch_dlsch(const uint8_t cc_idx, const uint32_t sib_index, uint8_t* payload) = 0; + virtual void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) = 0; /* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread. * PDU gets placed into the buffer and higher layer thread gets notified. */ @@ -371,10 +371,10 @@ public: class rrc_interface_rlc { public: - virtual void read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t* payload) = 0; - virtual void read_pdu_pcch(uint8_t* payload, uint32_t payload_size) = 0; - virtual void max_retx_attempted(uint16_t rnti) = 0; - virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; + virtual void read_pdu_bcch_dlsch(const uint8_t cc_idx, const uint32_t sib_index, uint8_t* payload) = 0; + virtual void read_pdu_pcch(uint8_t* payload, uint32_t payload_size) = 0; + virtual void max_retx_attempted(uint16_t rnti) = 0; + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; }; // RRC interface for MAC @@ -389,6 +389,29 @@ public: virtual bool is_paging_opportunity(uint32_t tti, uint32_t* payload_len) = 0; }; +// SCell configuration +struct scell_cfg_t { + uint32_t cell_id; + bool cross_carrier_sched = false; + uint32_t sched_cell_id; + bool ul_allowed; +}; + +// Cell/Sector configuration +struct cell_cfg_t { + uint32_t rf_port; + uint32_t cell_id; + uint16_t tac; + uint32_t pci; + uint16_t root_seq_idx; + uint32_t dl_earfcn; + float dl_freq_hz; + uint32_t ul_earfcn; + float ul_freq_hz; + std::vector scell_list; +}; +typedef std::vector cell_list_t; + // RRC interface for PDCP class rrc_interface_pdcp { @@ -482,6 +505,7 @@ typedef struct { } s1ap_args_t; typedef struct { + uint32_t nof_prb; ///< Needed to dimension MAC softbuffers for all cells sched_interface::sched_args_t sched; int link_failure_nof_err; } mac_args_t; diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 40152fe7f..64a4d3ad2 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -6,8 +6,6 @@ # eNB configuration # # enb_id: 20-bit eNB identifier. -# cell_id: 8-bit cell identifier. -# tac: 16-bit Tracking Area Code. # mcc: Mobile Country Code # mnc: Mobile Network Code # mme_addr: IP address of MME for S1 connnection @@ -20,9 +18,6 @@ ##################################################################### [enb] enb_id = 0x19B -cell_id = 0x01 -phy_cell_id = 1 -tac = 0x0007 mcc = 001 mnc = 01 mme_addr = 127.0.1.100 @@ -48,7 +43,7 @@ drb_config = drb.conf ##################################################################### # RF configuration # -# dl_earfcn: EARFCN code for DL +# dl_earfcn: EARFCN code for DL (only valid if a single cell is configured in rr.conf) # tx_gain: Transmit gain (dB). # rx_gain: Optional receive gain (dB). If disabled, AGC if enabled # @@ -64,7 +59,7 @@ drb_config = drb.conf # Default "auto". B210 USRP: 100 samples, bladeRF: 27. ##################################################################### [rf] -dl_earfcn = 3400 +#dl_earfcn = 3400 tx_gain = 80 rx_gain = 40 diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index d5e99243f..71e6230a9 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -59,10 +59,10 @@ namespace srsenb { *******************************************************************************/ struct enb_args_t { - uint32_t dl_earfcn; - uint32_t ul_earfcn; + std::string enb_id; + uint32_t dl_earfcn; // By default the EARFCN from rr.conf's cell list are used but this value can be used for single + // cell eNB uint32_t n_prb; - uint32_t pci; uint32_t nof_ports; uint32_t transmission_mode; float p_a; diff --git a/srsenb/hdr/parser.h b/srsenb/hdr/parser.h index 413a930af..6e168fe1c 100644 --- a/srsenb/hdr/parser.h +++ b/srsenb/hdr/parser.h @@ -370,6 +370,17 @@ int parse_default_field(T& obj, return ret; } +//! Parse required field and return error if field isn't specified +template > +int parse_required_field(T& obj, Setting& root, const char* field_name, const Parser& field_parser = {}) +{ + if (not root.exists(field_name)) { + fprintf(stderr, "PARSER ERROR: Field \"%s\" doesn't exist.\n", field_name); + return -1; + } + return field_parser(obj, root[field_name]); +} + template int parse_bounded_number(T& number, Setting& fieldroot, T num_min, T num_max) { diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index 9a140c452..d84f0741e 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -42,7 +42,7 @@ public: mac(); ~mac(); bool init(const mac_args_t& args_, - srslte_cell_t* cell, + const cell_list_t& cells_, phy_interface_stack_lte* phy, rlc_interface_mac* rlc, rrc_interface_mac* rrc, @@ -114,7 +114,7 @@ private: stack_interface_mac_lte* stack = nullptr; srslte::log* log_h = nullptr; - srslte_cell_t cell = {}; + cell_list_t cells = {}; mac_args_t args = {}; // derived from args @@ -137,7 +137,7 @@ private: int rar_idx, uint32_t pdu_len, uint32_t tti); - uint8_t* assemble_si(uint32_t index); + uint8_t* assemble_si(const uint8_t cc_idx, const uint32_t index); const static int rar_payload_len = 128; std::vector rar_pdu_msg; diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index c093dd2cb..245a4b355 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -74,13 +74,6 @@ struct meas_cell_cfg_t { float q_offset; }; -struct scell_cfg_t { - uint32_t cell_id; - bool cross_carrier_sched = false; - uint32_t sched_cell_id; - bool ul_allowed; -}; - // neigh measurement Cell info struct rrc_meas_cfg_t { std::vector meas_cells; @@ -92,23 +85,10 @@ struct rrc_meas_cfg_t { // TODO: Add multiple meas configs }; -// Cell/Sector configuration -struct cell_cfg_t { - uint32_t rf_port; - uint32_t cell_id; - uint16_t tac; - uint32_t pci; - uint16_t root_seq_idx; - uint32_t dl_earfcn; - float dl_freq_hz; - uint32_t ul_earfcn; - float ul_freq_hz; - std::vector scell_list; -}; - #define MAX_NOF_QCI 10 struct rrc_cfg_t { + uint32_t enb_id; ///< Required to pack SIB1 asn1::rrc::sib_type1_s sib1; asn1::rrc::sib_info_item_c sibs[ASN1_RRC_MAX_SIB]; asn1::rrc::mac_main_cfg_s mac_cnfg; @@ -119,16 +99,14 @@ struct rrc_cfg_t { rrc_cfg_sr_t sr_cfg; rrc_cfg_cqi_t cqi_cfg; rrc_cfg_qci_t qci_cfg[MAX_NOF_QCI]; - srslte_cell_t cell; bool enable_mbsfn; uint32_t inactivity_timeout_ms; srslte::CIPHERING_ALGORITHM_ID_ENUM eea_preference_list[srslte::CIPHERING_ALGORITHM_ID_N_ITEMS]; 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_list; - uint32_t pci; // TODO: add this to srslte_cell_t? - uint32_t dl_earfcn; // TODO: add this to srslte_cell_t? + srslte_cell_t cell; + cell_list_t cell_list; }; static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", @@ -148,7 +126,7 @@ public: rrc(); ~rrc(); - void init(rrc_cfg_t* cfg, + void init(const rrc_cfg_t& cfg_, phy_interface_rrc_lte* phy, mac_interface_rrc* mac, rlc_interface_rrc* rlc, @@ -170,7 +148,7 @@ public: bool is_paging_opportunity(uint32_t tti, uint32_t* payload_len) override; // rrc_interface_rlc - void read_pdu_bcch_dlsch(uint32_t sib_idx, uint8_t* payload) override; + void read_pdu_bcch_dlsch(const uint8_t cc_idx, const uint32_t sib_index, uint8_t* payload) override; void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) override; void max_retx_attempted(uint16_t rnti) override; @@ -390,7 +368,7 @@ private: std::map > users; // NOTE: has to have fixed addr std::map pending_paging; - std::vector sib_buffer; + std::map > sib_buffer; ///< Packed SIBs for each CC void process_release_complete(uint16_t rnti); void process_rl_failure(uint16_t rnti); diff --git a/srsenb/hdr/stack/upper/rlc.h b/srsenb/hdr/stack/upper/rlc.h index f614ced68..6d22b887b 100644 --- a/srsenb/hdr/stack/upper/rlc.h +++ b/srsenb/hdr/stack/upper/rlc.h @@ -64,7 +64,7 @@ public: // rlc_interface_mac int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes); - void read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t* payload); + void read_pdu_bcch_dlsch(const uint8_t cc_idx, const uint32_t sib_index, uint8_t* payload); void write_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes); void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size); diff --git a/srsenb/rr.conf.example b/srsenb/rr.conf.example index d8bb63de3..469ac0332 100644 --- a/srsenb/rr.conf.example +++ b/srsenb/rr.conf.example @@ -54,12 +54,12 @@ cell_list = ( { // rf_port = 0; - // cell_id = 0x01; - // tac = 0x0001; - // pci = 1; + cell_id = 0x01; + tac = 0x0001; + pci = 1; // root_seq_idx = 204; - // dl_earfcn = 3400; - // ul_earfcn = 21400; + dl_earfcn = 3400; + ul_earfcn = 21400; ho_active = false; // CA cells diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index ce156aa08..ab1127cd4 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -651,19 +651,6 @@ int parse_rr(all_args_t* args_, rrc_cfg_t* rrc_cfg_) p.add_section(&phy_cfg_); p.add_section(&rrc_cnfg); - // If the cell list is empty, use default values from enb.conf to keep backwards compatibility - if (rrc_cfg_->cell_list.empty()) { - rrc_cfg_->cell_list.resize(1); - cell_cfg_t& cell_cfg = rrc_cfg_->cell_list[0]; - cell_cfg.rf_port = 0; - cell_cfg.cell_id = 0; - cell_cfg.tac = args_->stack.s1ap.tac; - cell_cfg.pci = args_->enb.pci; - cell_cfg.root_seq_idx = rrc_cfg_->sibs[1].sib2().rr_cfg_common.prach_cfg.root_seq_idx; - cell_cfg.dl_earfcn = args_->enb.dl_earfcn; - cell_cfg.ul_earfcn = args_->enb.ul_earfcn; - } - return p.parse(); } @@ -672,7 +659,7 @@ static int parse_meas_cell_list(rrc_meas_cfg_t* meas_cfg, Setting& root) meas_cfg->meas_cells.resize(root.getLength()); for (uint32_t i = 0; i < meas_cfg->meas_cells.size(); ++i) { meas_cfg->meas_cells[i].earfcn = root[i]["dl_earfcn"]; - meas_cfg->meas_cells[i].pci = (unsigned int)root[i]["pci"] % 504; + meas_cfg->meas_cells[i].pci = (unsigned int)root[i]["pci"] % SRSLTE_NUM_PCI; meas_cfg->meas_cells[i].eci = (unsigned int)root[i]["eci"]; meas_cfg->meas_cells[i].q_offset = 0; // LIBLTE_RRC_Q_OFFSET_RANGE_DB_0; // TODO // // TODO: TEMP @@ -715,7 +702,6 @@ static int parse_meas_report_desc(rrc_meas_cfg_t* meas_cfg, Setting& root) static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) { auto cell_id_parser = [](uint32_t& cell_id, Setting& root) { return parse_bounded_number(cell_id, root, 0u, 255u); }; - uint32_t self_cellid = args->stack.s1ap.cell_id & 0xFFu; rrc_cfg->cell_list.resize(root.getLength()); for (uint32_t n = 0; n < rrc_cfg->cell_list.size(); ++n) { @@ -723,13 +709,14 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) auto& cellroot = root[n]; parse_opt_field(cell_cfg.rf_port, cellroot, "rf_port"); - parse_default_field(cell_cfg.cell_id, cellroot, "cell_id", self_cellid, cell_id_parser); - parse_default_field(cell_cfg.tac, cellroot, "tac", args->stack.s1ap.tac); - parse_default_field(cell_cfg.pci, cellroot, "pci", args->enb.pci); + HANDLEPARSERCODE(parse_required_field(cell_cfg.cell_id, cellroot, "cell_id")); + HANDLEPARSERCODE(parse_required_field(cell_cfg.tac, cellroot, "tac")); + HANDLEPARSERCODE(parse_required_field(cell_cfg.pci, cellroot, "pci")); + cell_cfg.pci = cell_cfg.pci % SRSLTE_NUM_PCI; + HANDLEPARSERCODE(parse_required_field(cell_cfg.dl_earfcn, cellroot, "dl_earfcn")); + HANDLEPARSERCODE(parse_required_field(cell_cfg.ul_earfcn, cellroot, "ul_earfcn")); parse_default_field( cell_cfg.root_seq_idx, cellroot, "root_seq_idx", rrc_cfg->sibs[1].sib2().rr_cfg_common.prach_cfg.root_seq_idx); - cell_cfg.dl_earfcn = cellroot["dl_earfcn"]; - cell_cfg.ul_earfcn = cellroot["ul_earfcn"]; if (cellroot["ho_active"]) { HANDLEPARSERCODE(parse_meas_cell_list(&rrc_cfg->meas_cfg, cellroot["meas_cell_list"])); @@ -778,13 +765,12 @@ namespace enb_conf_sections { int parse_cell_cfg(all_args_t* args_, srslte_cell_t* cell) { cell->frame_type = SRSLTE_FDD; - cell->id = args_->enb.pci; cell->cp = SRSLTE_CP_NORM; cell->nof_ports = args_->enb.nof_ports; cell->nof_prb = args_->enb.n_prb; + // PCI not configured yet phich_cfg_s phichcfg; - parser::section phy_cnfg("phy_cnfg"); parser::section phich_cnfg("phich_cnfg"); phy_cnfg.add_subsection(&phich_cnfg); @@ -853,7 +839,7 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_) return SRSLTE_ERROR; } } catch (const SettingTypeException& stex) { - fprintf(stderr, "\"Error parsing DRB configuration: %s\n", stex.getPath()); + fprintf(stderr, "Error parsing DRB configuration: %s\n", stex.getPath()); return SRSLTE_ERROR; } catch (const ConfigException& cex) { fprintf(stderr, "Error parsing DRB configuration\n"); @@ -861,18 +847,61 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_) } // Set fields derived from others, and check for correctness of the parsed configuration - return enb_conf_sections::set_derived_args(args_, rrc_cfg_, phy_cfg_, &cell_common_cfg); + return enb_conf_sections::set_derived_args(args_, rrc_cfg_, phy_cfg_, cell_common_cfg); } -int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_, srslte_cell_t* cell_cfg_) +int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_, const srslte_cell_t& cell_cfg_) { - // Copy cell struct to rrc and phy - rrc_cfg_->cell = *cell_cfg_; + // Sanity check + if (rrc_cfg_->cell_list.empty()) { + ERROR("No cell specified in RR config."); + return SRSLTE_ERROR; + } + + // Check for a forced DL EARFCN or frequency (only valid for a single cell config (Xico's favorite feature)) + if (rrc_cfg_->cell_list.size() == 1) { + auto& cfg = rrc_cfg_->cell_list.at(0); + if (args_->enb.dl_earfcn > 0) { + cfg.dl_earfcn = args_->enb.dl_earfcn; + ERROR("Force DL EARFCN for cell PCI=%d to %d\n", cfg.pci, cfg.dl_earfcn); + } + if (args_->rf.dl_freq > 0) { + cfg.dl_freq_hz = args_->rf.dl_freq; + ERROR("Force DL freq for cell PCI=%d to %f MHz\n", cfg.pci, cfg.dl_freq_hz / 1e6f); + } + } else { + // If more than one cell is defined, single EARFCN or DL freq will be ignored + if (args_->enb.dl_earfcn > 0 || args_->rf.dl_freq > 0) { + INFO("Multiple cells defined in rr.conf. Ignoring single EARFCN and/or frequency config.\n"); + } + } + + // set config for RRC's base cell + rrc_cfg_->cell = cell_cfg_; + + // Set S1AP related params from cell list (Convert hex strings) + { + std::stringstream sstr; + sstr << std::hex << args_->enb.enb_id; + sstr >> args_->stack.s1ap.enb_id; + } + { + std::stringstream sstr; + sstr << std::hex << rrc_cfg_->cell_list.at(0).cell_id; + uint16_t tmp; // Need intermediate uint16_t as uint8_t is treated as char + sstr >> tmp; + args_->stack.s1ap.cell_id = tmp; + } + { + std::stringstream sstr; + sstr << std::hex << rrc_cfg_->cell_list.at(0).tac; + sstr >> args_->stack.s1ap.tac; + } // Create dedicated cell configuration from RRC configuration for (auto& cfg : rrc_cfg_->cell_list) { phy_cell_cfg_t phy_cell_cfg = {}; - phy_cell_cfg.cell = *cell_cfg_; + phy_cell_cfg.cell = cell_cfg_; phy_cell_cfg.cell.id = cfg.pci; phy_cell_cfg.cell_id = cfg.cell_id; phy_cell_cfg.root_seq_idx = cfg.root_seq_idx; @@ -906,16 +935,12 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ rrc_cfg_->inactivity_timeout_ms = args_->general.rrc_inactivity_timer; rrc_cfg_->enable_mbsfn = args_->stack.embms.enable; - rrc_cfg_->dl_earfcn = args_->enb.dl_earfcn; - rrc_cfg_->pci = args_->enb.pci; - // Check number of control symbols - if (cell_cfg_->nof_prb < 50 && args_->stack.mac.sched.nof_ctrl_symbols != 3) { + if (cell_cfg_.nof_prb < 50 && args_->stack.mac.sched.nof_ctrl_symbols != 3) { args_->stack.mac.sched.nof_ctrl_symbols = 3; - fprintf(stdout, - "Setting number of control symbols to %d for %d PRB cell.\n", - args_->stack.mac.sched.nof_ctrl_symbols, - cell_cfg_->nof_prb); + INFO("Setting number of control symbols to %d for %d PRB cell.\n", + args_->stack.mac.sched.nof_ctrl_symbols, + cell_cfg_.nof_prb); } // Parse EEA preference list @@ -968,9 +993,9 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ // Check PRACH configuration uint32_t prach_freq_offset = rrc_cfg_->sibs[1].sib2().rr_cfg_common.prach_cfg.prach_cfg_info.prach_freq_offset; - if (rrc_cfg_->cell.nof_prb > 10) { + if (args_->enb.n_prb > 10) { uint32_t lower_bound = SRSLTE_MAX(rrc_cfg_->sr_cfg.nof_prb, rrc_cfg_->cqi_cfg.nof_prb); - uint32_t upper_bound = rrc_cfg_->cell.nof_prb - lower_bound; + uint32_t upper_bound = args_->enb.n_prb - lower_bound; if (prach_freq_offset + 6 > upper_bound or prach_freq_offset < lower_bound) { fprintf(stderr, "ERROR: Invalid PRACH configuration - prach_freq_offset=%d collides with PUCCH.\n", @@ -982,12 +1007,12 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ return SRSLTE_ERROR; } } else { // 6 PRB case - if (prach_freq_offset + 6 > rrc_cfg_->cell.nof_prb) { + if (prach_freq_offset + 6 > args_->enb.n_prb) { fprintf(stderr, "WARNING: Invalid PRACH configuration - prach=(%d, %d) does not fit into the eNB PRBs=(0, %d).\n", prach_freq_offset, prach_freq_offset + 6, - rrc_cfg_->cell.nof_prb); + args_->enb.n_prb); fprintf( stderr, " Consider changing the \"prach_freq_offset\" value to 0 in the sib.conf file when using 6 PRBs.\n"); @@ -1001,6 +1026,12 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ args_->rf.nof_carriers = rrc_cfg_->cell_list.size(); args_->rf.nof_antennas = args_->enb.nof_ports; + // MAC needs to know the cell bandwidth to dimension softbuffers + args_->stack.mac.nof_prb = args_->enb.n_prb; + + // RRC needs eNB id for SIB1 packing + rrc_cfg_->enb_id = args_->stack.s1ap.enb_id; + return SRSLTE_SUCCESS; } @@ -1390,10 +1421,6 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co } // 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); 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); @@ -1404,6 +1431,7 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co ERROR("The provided mnc=%d is not valid", args_->stack.s1ap.mcc); return -1; } + sib_type1_s::cell_access_related_info_s_* cell_access = &sib1->cell_access_related_info; cell_access->plmn_id_list.resize(1); srslte::plmn_id_t plmn; if (plmn.from_string(mcc_str + mnc_str) == SRSLTE_ERROR) { @@ -1424,9 +1452,7 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co if (sib2->freq_info.ul_bw_present) { 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; - } + // UL carrier freq is patched before packing the SIB for each CC // Update MBSFN list counter. Only 1 supported if (not args_->stack.embms.enable) { diff --git a/srsenb/src/enb_cfg_parser.h b/srsenb/src/enb_cfg_parser.h index c268e6725..e16c07a20 100644 --- a/srsenb/src/enb_cfg_parser.h +++ b/srsenb/src/enb_cfg_parser.h @@ -47,7 +47,7 @@ namespace enb_conf_sections { int parse_cell_cfg(all_args_t* args_, srslte_cell_t* cell); int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_); -int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_, srslte_cell_t* cell_cfg_); +int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_, const srslte_cell_t& cell_cfg_); } // namespace enb_conf_sections diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index b907c87c3..4d6270b31 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -49,9 +49,6 @@ string config_file; void parse_args(all_args_t* args, int argc, char* argv[]) { - string enb_id; - string cell_id; - string tac; string mcc; string mnc; @@ -67,16 +64,13 @@ void parse_args(all_args_t* args, int argc, char* argv[]) bpo::options_description common("Configuration options"); common.add_options() - ("enb.enb_id", bpo::value(&enb_id)->default_value("0x0"), "eNodeB ID") + ("enb.enb_id", bpo::value(&args->enb.enb_id)->default_value("0x0"), "eNodeB ID") ("enb.name", bpo::value(&args->stack.s1ap.enb_name)->default_value("srsenb01"), "eNodeB Name") - ("enb.cell_id", bpo::value(&cell_id)->default_value("0x0"), "Cell ID") - ("enb.tac", bpo::value(&tac)->default_value("0x0"), "Tracking Area Code") ("enb.mcc", bpo::value(&mcc)->default_value("001"), "Mobile Country Code") ("enb.mnc", bpo::value(&mnc)->default_value("01"), "Mobile Network Code") ("enb.mme_addr", bpo::value(&args->stack.s1ap.mme_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connection") ("enb.gtp_bind_addr", bpo::value(&args->stack.s1ap.gtp_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for GTP connection") ("enb.s1c_bind_addr", bpo::value(&args->stack.s1ap.s1c_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for S1AP connection") - ("enb.phy_cell_id", bpo::value(&args->enb.pci)->default_value(0), "Physical Cell Identity (PCI)") ("enb.n_prb", bpo::value(&args->enb.n_prb)->default_value(25), "Number of PRB") ("enb.nof_ports", bpo::value(&args->enb.nof_ports)->default_value(1), "Number of ports") ("enb.tm", bpo::value(&args->enb.transmission_mode)->default_value(1), "Transmission mode (1-8)") @@ -86,8 +80,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("enb_files.rr_config", bpo::value(&args->enb_files.rr_config)->default_value("rr.conf"), "RR configuration files") ("enb_files.drb_config", bpo::value(&args->enb_files.drb_config)->default_value("drb.conf"), "DRB configuration files") - ("rf.dl_earfcn", bpo::value(&args->enb.dl_earfcn)->default_value(3400), "Downlink EARFCN") - ("rf.ul_earfcn", bpo::value(&args->enb.ul_earfcn)->default_value(0), "Uplink EARFCN (Default based on Downlink EARFCN)") + ("rf.dl_earfcn", bpo::value(&args->enb.dl_earfcn)->default_value(0), "Force Downlink EARFCN for single cell") ("rf.rx_gain", bpo::value(&args->rf.rx_gain)->default_value(50), "Front-end receiver gain") ("rf.tx_gain", bpo::value(&args->rf.tx_gain)->default_value(70), "Front-end transmitter gain") ("rf.dl_freq", bpo::value(&args->rf.dl_freq)->default_value(-1), "Downlink Frequency (if positive overrides EARFCN)") @@ -252,25 +245,6 @@ void parse_args(all_args_t* args, int argc, char* argv[]) exit(1); } - // Convert hex strings - { - std::stringstream sstr; - sstr << std::hex << vm["enb.enb_id"].as(); - sstr >> args->stack.s1ap.enb_id; - } - { - std::stringstream sstr; - sstr << std::hex << vm["enb.cell_id"].as(); - uint16_t tmp; // Need intermediate uint16_t as uint8_t is treated as char - sstr >> tmp; - args->stack.s1ap.cell_id = tmp; - } - { - std::stringstream sstr; - sstr << std::hex << vm["enb.tac"].as(); - sstr >> args->stack.s1ap.tac; - } - // Convert MCC/MNC strings if (!srslte::string_to_mcc(mcc, &args->stack.s1ap.mcc)) { cout << "Error parsing enb.mcc:" << mcc << " - must be a 3-digit string." << endl; @@ -279,24 +253,6 @@ void parse_args(all_args_t* args, int argc, char* argv[]) cout << "Error parsing enb.mnc:" << mnc << " - must be a 2 or 3-digit string." << endl; } - // Convert UL/DL EARFCN to frequency if needed - if (args->rf.dl_freq < 0) { - args->rf.dl_freq = 1e6 * srslte_band_fd(args->enb.dl_earfcn); - if (args->rf.dl_freq < 0) { - fprintf(stderr, "Error getting DL frequency for EARFCN=%d\n", args->enb.dl_earfcn); - exit(1); - } - } - if (args->rf.ul_freq < 0) { - if (args->enb.ul_earfcn == 0) { - args->enb.ul_earfcn = srslte_band_ul_earfcn(args->enb.dl_earfcn); - } - args->rf.ul_freq = 1e6 * srslte_band_fu(args->enb.ul_earfcn); - if (args->rf.ul_freq < 0) { - fprintf(stderr, "Error getting UL frequency for EARFCN=%d\n", args->enb.dl_earfcn); - exit(1); - } - } if (args->stack.embms.enable) { if (args->stack.mac.sched.nof_ctrl_symbols == 3) { fprintf(stderr, diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 46ffd0362..6035a80eb 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -106,10 +106,10 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_) rx_sockets.reset(new srslte::rx_multisocket_handler("ENBSOCKETS", &stack_log)); // Init all layers - mac.init(args.mac, &rrc_cfg.cell, phy, &rlc, &rrc, this, &mac_log); + mac.init(args.mac, rrc_cfg.cell_list, phy, &rlc, &rrc, this, &mac_log); rlc.init(&pdcp, &rrc, &mac, &timers, &rlc_log); pdcp.init(&rlc, &rrc, >pu); - rrc.init(&rrc_cfg, phy, &mac, &rlc, &pdcp, &s1ap, >pu, &timers, &rrc_log); + rrc.init(rrc_cfg, phy, &mac, &rlc, &pdcp, &s1ap, >pu, &timers, &rrc_log); s1ap.init(args.s1ap, &rrc, &timers, this); gtpu.init(args.s1ap.gtp_bind_addr, args.s1ap.mme_addr, diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index e91f78117..6d150ec81 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -51,7 +51,7 @@ mac::~mac() } bool mac::init(const mac_args_t& args_, - srslte_cell_t* cell_, + const cell_list_t& cells_, phy_interface_stack_lte* phy, rlc_interface_mac* rlc, rrc_interface_mac* rrc, @@ -60,7 +60,7 @@ bool mac::init(const mac_args_t& args_, { started = false; - if (cell_ && phy && rlc && log_h_) { + if (phy && rlc && log_h_) { phy_h = phy; rlc_h = rlc; rrc_h = rrc; @@ -68,7 +68,7 @@ bool mac::init(const mac_args_t& args_, log_h = log_h_; args = args_; - cell = *cell_; + cells = cells_; stack_task_queue = stack->get_task_queue(); @@ -79,13 +79,13 @@ bool mac::init(const mac_args_t& args_, // Init softbuffer for SI messages for (int i = 0; i < NOF_BCCH_DLSCH_MSG; i++) { - srslte_softbuffer_tx_init(&bcch_softbuffer_tx[i], cell.nof_prb); + srslte_softbuffer_tx_init(&bcch_softbuffer_tx[i], args.nof_prb); } // Init softbuffer for PCCH - srslte_softbuffer_tx_init(&pcch_softbuffer_tx, cell.nof_prb); + srslte_softbuffer_tx_init(&pcch_softbuffer_tx, args.nof_prb); // Init softbuffer for RAR - srslte_softbuffer_tx_init(&rar_softbuffer_tx, cell.nof_prb); + srslte_softbuffer_tx_init(&rar_softbuffer_tx, args.nof_prb); reset(); @@ -430,7 +430,7 @@ void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx // Create new UE if (ue_db.count(rnti) == 0) { - ue_db[rnti] = new ue(rnti, cell.nof_prb, &scheduler, rrc_h, rlc_h, log_h, SRSLTE_FDD_NOF_HARQ); + ue_db[rnti] = new ue(rnti, args.nof_prb, &scheduler, rrc_h, rlc_h, log_h, SRSLTE_FDD_NOF_HARQ); } // Set PCAP if available @@ -581,7 +581,7 @@ int mac::get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res_list) // Set softbuffer if (sched_result.bc[i].type == sched_interface::dl_sched_bc_t::BCCH) { dl_sched_res->pdsch[n].softbuffer_tx[0] = &bcch_softbuffer_tx[sched_result.bc[i].index]; - dl_sched_res->pdsch[n].data[0] = assemble_si(sched_result.bc[i].index); + dl_sched_res->pdsch[n].data[0] = assemble_si(enb_cc_idx, sched_result.bc[i].index); #ifdef WRITE_SIB_PCAP if (pcap) { pcap->write_dl_sirnti(dl_sched_res->pdsch[n].data[0], sched_result.bc[i].tbs, true, tti, enb_cc_idx); @@ -739,9 +739,9 @@ uint8_t* mac::assemble_rar(sched_interface::dl_sched_rar_grant_t* grants, } } -uint8_t* mac::assemble_si(uint32_t index) +uint8_t* mac::assemble_si(const uint8_t cc_idx, const uint32_t index) { - rlc_h->read_pdu_bcch_dlsch(index, bcch_dlsch_payload); + rlc_h->read_pdu_bcch_dlsch(cc_idx, index, bcch_dlsch_payload); return bcch_dlsch_payload; } @@ -833,7 +833,7 @@ void mac::write_mcch(sib_type2_s* sib2_, sib_type13_r9_s* sib13_, mcch_msg_s* mc mcch.pack(bref); current_mcch_length = bref.distance_bytes(&mcch_payload_buffer[1]); current_mcch_length = current_mcch_length + rlc_header_len; - ue_db[SRSLTE_MRNTI] = new ue(SRSLTE_MRNTI, cell.nof_prb, &scheduler, rrc_h, rlc_h, log_h); + ue_db[SRSLTE_MRNTI] = new ue(SRSLTE_MRNTI, args.nof_prb, &scheduler, rrc_h, rlc_h, log_h); rrc_h->add_user(SRSLTE_MRNTI, {}); } diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 2c9ad7edf..440c64cbe 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -43,7 +43,7 @@ rrc::rrc() rrc::~rrc() {} -void rrc::init(rrc_cfg_t* cfg_, +void rrc::init(const rrc_cfg_t& cfg_, phy_interface_rrc_lte* phy_, mac_interface_rrc* mac_, rlc_interface_rrc* rlc_, @@ -64,10 +64,10 @@ void rrc::init(rrc_cfg_t* cfg_, pool = srslte::byte_buffer_pool::get_instance(); - cfg = *cfg_; + cfg = cfg_; if (cfg.sibs[12].type() == asn1::rrc::sys_info_r8_ies_s::sib_type_and_info_item_c_::types::sib13_v920 && - cfg_->enable_mbsfn) { + cfg.enable_mbsfn) { configure_mbsfn_sibs(&cfg.sibs[1].sib2(), &cfg.sibs[12].sib13_v920()); } @@ -126,10 +126,10 @@ void rrc::get_metrics(rrc_metrics_t& m) to the queue and process later *******************************************************************************/ -void rrc::read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t* payload) +void rrc::read_pdu_bcch_dlsch(const uint8_t cc_idx, const uint32_t sib_index, uint8_t* payload) { - if (sib_index < ASN1_RRC_MAX_SIB) { - memcpy(payload, sib_buffer[sib_index]->msg, sib_buffer[sib_index]->N_bytes); + if (sib_index < ASN1_RRC_MAX_SIB && cc_idx < sib_buffer.size()) { + memcpy(payload, sib_buffer.at(cc_idx).at(sib_index)->msg, sib_buffer.at(cc_idx).at(sib_index)->N_bytes); } } @@ -776,7 +776,7 @@ void rrc::config_mac() // set sib/prach cfg for (uint32_t i = 0; i < nof_si_messages; i++) { - item.sibs[i].len = sib_buffer[i]->N_bytes; + item.sibs[i].len = sib_buffer.at(ccidx).at(i)->N_bytes; if (i == 0) { item.sibs[i].period_rf = 8; // SIB1 is always 8 rf } else { @@ -794,7 +794,7 @@ void rrc::config_mac() item.nrb_pucch = SRSLTE_MAX(cfg.sr_cfg.nof_prb, cfg.cqi_cfg.nof_prb); rrc_log->info("Allocating %d PRBs for PUCCH\n", item.nrb_pucch); - // Copy Cell configuration + // Copy base cell configuration item.cell = cfg.cell; // copy secondary cell list info @@ -821,58 +821,90 @@ void rrc::config_mac() mac->cell_cfg(sched_cfg); } +/* This methods packs the SIBs for each component carrier and stores them + * inside the sib_buffer, a vector of SIBs for each CC. + * + * Before packing the message, it patches the cell specific params of + * the SIB, including the cellId and the PRACH config index. + * + * @return The number of SIBs messages per CC + */ uint32_t rrc::generate_sibs() { // nof_messages includes SIB2 by default, plus all configured SIBs uint32_t nof_messages = 1 + cfg.sib1.sched_info_list.size(); sched_info_list_l& sched_info = cfg.sib1.sched_info_list; - // msg is array of SI messages, each SI message msg[i] may contain multiple SIBs - // all SIBs in a SI message msg[i] share the same periodicity - asn1::dyn_array msg(nof_messages + 1); + // generate SIBs for each CC + for (uint8_t cc_idx = 0; cc_idx < cfg.cell_list.size(); cc_idx++) { + // msg is array of SI messages, each SI message msg[i] may contain multiple SIBs + // all SIBs in a SI message msg[i] share the same periodicity + asn1::dyn_array msg(nof_messages + 1); - // Copy SIB1 to first SI message - msg[0].msg.set_c1().set_sib_type1() = cfg.sib1; + // Copy SIB1 to first SI message + msg[0].msg.set_c1().set_sib_type1() = cfg.sib1; - // Copy rest of SIBs - for (uint32_t sched_info_elem = 0; sched_info_elem < nof_messages - 1; sched_info_elem++) { - uint32_t msg_index = sched_info_elem + 1; // first msg is SIB1, therefore start with second + // Update cellId + sib_type1_s::cell_access_related_info_s_* cell_access = &msg[0].msg.c1().sib_type1().cell_access_related_info; + cell_access->cell_id.from_number((cfg.enb_id << 8u) + cfg.cell_list.at(cc_idx).cell_id); + cell_access->tac.from_number(cfg.cell_list.at(cc_idx).tac); - msg[msg_index].msg.set_c1().set_sys_info().crit_exts.set_sys_info_r8(); - sys_info_r8_ies_s::sib_type_and_info_l_& sib_list = - msg[msg_index].msg.c1().sys_info().crit_exts.sys_info_r8().sib_type_and_info; + // Update DL EARFCN + msg[0].msg.c1().sib_type1().freq_band_ind = (uint8_t)srslte_band_get_band(cfg.cell_list.at(cc_idx).dl_earfcn); - // SIB2 always in second SI message - if (msg_index == 1) { - sib_list.push_back(cfg.sibs[1]); - // Save SIB2 - sib2 = cfg.sibs[1].sib2(); - } + // Copy rest of SIBs + for (uint32_t sched_info_elem = 0; sched_info_elem < nof_messages - 1; sched_info_elem++) { + uint32_t msg_index = sched_info_elem + 1; // first msg is SIB1, therefore start with second - // Add other SIBs to this message, if any - for (auto& mapping_enum : sched_info[sched_info_elem].sib_map_info) { - sib_list.push_back(cfg.sibs[(int)mapping_enum + 2]); - } - } + msg[msg_index].msg.set_c1().set_sys_info().crit_exts.set_sys_info_r8(); + sys_info_r8_ies_s::sib_type_and_info_l_& sib_list = + msg[msg_index].msg.c1().sys_info().crit_exts.sys_info_r8().sib_type_and_info; + + // SIB2 always in second SI message + if (msg_index == 1) { + // update PRACH root seq index for this cell + cfg.sibs[1].sib2().rr_cfg_common.prach_cfg.root_seq_idx = cfg.cell_list.at(cc_idx).root_seq_idx; + + // update carrier freq + if (cfg.sibs[1].sib2().freq_info.ul_carrier_freq_present) { + cfg.sibs[1].sib2().freq_info.ul_carrier_freq = cfg.cell_list.at(cc_idx).ul_earfcn; + } - // Pack payload for all messages - for (uint32_t msg_index = 0; msg_index < nof_messages; msg_index++) { - srslte::unique_byte_buffer_t sib = srslte::allocate_unique_buffer(*pool); - asn1::bit_ref bref(sib->msg, sib->get_tailroom()); - asn1::bit_ref bref0 = bref; - if (msg[msg_index].pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { - rrc_log->error("Failed to pack SIB message %d\n", msg_index); + sib_list.push_back(cfg.sibs[1]); + + // Save SIB2 + sib2 = cfg.sibs[1].sib2(); + } + + // Add other SIBs to this message, if any + for (auto& mapping_enum : sched_info[sched_info_elem].sib_map_info) { + sib_list.push_back(cfg.sibs[(int)mapping_enum + 2]); + } } - sib->N_bytes = static_cast((bref.distance(bref0) - 1) / 8 + 1); - sib_buffer.push_back(std::move(sib)); - // Log SIBs in JSON format - log_rrc_message( - "SIB payload", Tx, sib_buffer[msg_index].get(), msg[msg_index], msg[msg_index].msg.c1().type().to_string()); - } + // Pack payload for all messages + for (uint32_t msg_index = 0; msg_index < nof_messages; msg_index++) { + srslte::unique_byte_buffer_t sib = srslte::allocate_unique_buffer(*pool); + asn1::bit_ref bref(sib->msg, sib->get_tailroom()); + asn1::bit_ref bref0 = bref; + if (msg[msg_index].pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { + rrc_log->error("Failed to pack SIB message %d\n", msg_index); + } + sib->N_bytes = static_cast((bref.distance(bref0) - 1) / 8 + 1); + sib_buffer[cc_idx].push_back(std::move(sib)); + + // Log SIBs in JSON format + std::string log_msg("CC" + std::to_string(cc_idx) + " SIB payload"); + log_rrc_message(log_msg, + Tx, + sib_buffer.at(cc_idx).at(msg_index).get(), + msg[msg_index], + msg[msg_index].msg.c1().type().to_string()); + } - if (cfg.sibs[6].type() == asn1::rrc::sys_info_r8_ies_s::sib_type_and_info_item_c_::types::sib7) { - sib7 = cfg.sibs[6].sib7(); + if (cfg.sibs[6].type() == asn1::rrc::sys_info_r8_ies_s::sib_type_and_info_item_c_::types::sib7) { + sib7 = cfg.sibs[6].sib7(); + } } return nof_messages; diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index e5dc6ed61..864ed54ef 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -861,15 +861,16 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci, hoprep_r8.as_cfg.source_sib_type1 = rrc_enb->cfg.sib1; hoprep_r8.as_cfg.source_sib_type2 = rrc_enb->sib2; asn1::number_to_enum(hoprep_r8.as_cfg.ant_info_common.ant_ports_count, rrc_enb->cfg.cell.nof_ports); - hoprep_r8.as_cfg.source_dl_carrier_freq = rrc_enb->cfg.dl_earfcn; + hoprep_r8.as_cfg.source_dl_carrier_freq = + rrc_enb->cfg.cell_list.at(0).dl_earfcn; // TODO: use actual DL EARFCN of source cell // - fill as_context hoprep_r8.as_context_present = true; hoprep_r8.as_context.reest_info_present = true; - hoprep_r8.as_context.reest_info.source_pci = rrc_enb->cfg.pci; + hoprep_r8.as_context.reest_info.source_pci = rrc_enb->cfg.cell_list.at(0).pci; // TODO: use actual PCI of source cell hoprep_r8.as_context.reest_info.target_cell_short_mac_i.from_number( rrc_details::compute_mac_i(rrc_ue->rnti, rrc_enb->cfg.sib1.cell_access_related_info.cell_id.to_number(), - rrc_enb->cfg.pci, + rrc_enb->cfg.cell_list.at(0).pci, // TODO: use actual PCI of source cell rrc_ue->integ_algo, rrc_ue->k_rrc_int)); diff --git a/srsenb/src/stack/upper/rlc.cc b/srsenb/src/stack/upper/rlc.cc index 779529e19..13d131011 100644 --- a/srsenb/src/stack/upper/rlc.cc +++ b/srsenb/src/stack/upper/rlc.cc @@ -193,10 +193,10 @@ void rlc::write_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof pthread_rwlock_unlock(&rwlock); } -void rlc::read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t* payload) +void rlc::read_pdu_bcch_dlsch(const uint8_t cc_idx, const uint32_t sib_index, uint8_t* payload) { // RLC is transparent for BCCH - rrc->read_pdu_bcch_dlsch(sib_index, payload); + rrc->read_pdu_bcch_dlsch(cc_idx, sib_index, payload); } void rlc::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) diff --git a/srsenb/test/upper/erab_setup_test.cc b/srsenb/test/upper/erab_setup_test.cc index 6435cbed5..89c89a2d9 100644 --- a/srsenb/test/upper/erab_setup_test.cc +++ b/srsenb/test/upper/erab_setup_test.cc @@ -46,7 +46,7 @@ int test_erab_setup(bool qci_exists) gtpu_dummy gtpu; rrc_log->set_level(srslte::LOG_LEVEL_INFO); rrc_log->set_hex_limit(1024); - rrc.init(&cfg, &phy, &mac, &rlc, &pdcp, &s1ap, >pu, &timers, rrc_log.get()); + rrc.init(cfg, &phy, &mac, &rlc, &pdcp, &s1ap, >pu, &timers, rrc_log.get()); auto tic = [&timers, &rrc] { timers.step_all(); diff --git a/srsenb/test/upper/rrc_mobility_test.cc b/srsenb/test/upper/rrc_mobility_test.cc index 6d24049aa..2bdd698d1 100644 --- a/srsenb/test/upper/rrc_mobility_test.cc +++ b/srsenb/test/upper/rrc_mobility_test.cc @@ -282,7 +282,7 @@ int test_mobility_class(mobility_test_params test_params) gtpu_dummy gtpu; rrc_log->set_level(srslte::LOG_LEVEL_INFO); rrc_log->set_hex_limit(1024); - rrc.init(&cfg, &phy, &mac, &rlc, &pdcp, &s1ap, >pu, &timers, rrc_log.get()); + rrc.init(cfg, &phy, &mac, &rlc, &pdcp, &s1ap, >pu, &timers, rrc_log.get()); auto tic = [&timers, &rrc] { timers.step_all();