mirror of https://github.com/PentHertz/srsLTE.git
srsue,nr: decode SIB1 based on coreset0 configuration in MIB
This commit is contained in:
parent
bfe69deccc
commit
b3497c4a94
|
@ -94,6 +94,7 @@ bool make_phy_tdd_cfg(const srsran_duplex_config_nr_t& srsran_duplex_config
|
|||
bool make_phy_harq_ack_cfg(const asn1::rrc_nr::phys_cell_group_cfg_s& phys_cell_group_cfg,
|
||||
srsran_harq_ack_cfg_hl_t* srsran_ue_dl_nr_harq_ack_cfg);
|
||||
bool make_phy_coreset_cfg(const asn1::rrc_nr::ctrl_res_set_s& ctrl_res_set, srsran_coreset_t* srsran_coreset);
|
||||
void make_phy_search_space0_cfg(srsran_search_space_t* in_srsran_search_space);
|
||||
bool make_phy_search_space_cfg(const asn1::rrc_nr::search_space_s& search_space,
|
||||
srsran_search_space_t* srsran_search_space);
|
||||
bool make_phy_csi_report(const asn1::rrc_nr::csi_report_cfg_s& csi_report_cfg,
|
||||
|
|
|
@ -197,6 +197,9 @@ public:
|
|||
|
||||
// RRC informs MAC about new UE identity for contention-free RA
|
||||
virtual bool set_crnti(const uint16_t crnti) = 0;
|
||||
|
||||
// RRC informs MAC to start/stop search for BCCH messages
|
||||
virtual void bcch_search(bool enabled) = 0;
|
||||
};
|
||||
|
||||
struct phy_args_nr_t {
|
||||
|
|
|
@ -503,6 +503,21 @@ bool make_phy_harq_ack_cfg(const phys_cell_group_cfg_s& phys_cell_group_cfg,
|
|||
return true;
|
||||
}
|
||||
|
||||
void make_phy_search_space0_cfg(srsran_search_space_t* in_srsran_search_space)
|
||||
{
|
||||
in_srsran_search_space->id = 0;
|
||||
in_srsran_search_space->coreset_id = 0;
|
||||
in_srsran_search_space->type = srsran_search_space_type_common_0;
|
||||
in_srsran_search_space->nof_candidates[0] = 0;
|
||||
in_srsran_search_space->nof_candidates[1] = 0;
|
||||
in_srsran_search_space->nof_candidates[2] = 4;
|
||||
in_srsran_search_space->nof_candidates[3] = 2;
|
||||
in_srsran_search_space->nof_candidates[4] = 0;
|
||||
in_srsran_search_space->nof_formats = 1;
|
||||
in_srsran_search_space->formats[0] = srsran_dci_format_nr_1_0;
|
||||
in_srsran_search_space->duration = 1;
|
||||
}
|
||||
|
||||
bool make_phy_search_space_cfg(const search_space_s& search_space, srsran_search_space_t* in_srsran_search_space)
|
||||
{
|
||||
srsran_search_space_t srsran_search_space = {};
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
void process_pdus(); /// Called by MAC to process received PDUs
|
||||
|
||||
// HARQ interface
|
||||
void push_bcch(srsran::unique_byte_buffer_t pdu);
|
||||
void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti);
|
||||
void push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tti);
|
||||
uint64_t get_received_crueid();
|
||||
|
@ -55,6 +56,7 @@ private:
|
|||
|
||||
///< currently only DCH PDUs supported (add BCH, PCH, etc)
|
||||
srsran::block_queue<srsran::unique_byte_buffer_t> pdu_queue;
|
||||
srsran::block_queue<srsran::unique_byte_buffer_t> bcch_queue;
|
||||
|
||||
srsran::mac_sch_pdu_nr rx_pdu;
|
||||
srsran::mac_sch_pdu_nr rx_pdu_tcrnti;
|
||||
|
|
|
@ -109,6 +109,7 @@ public:
|
|||
/// RRC
|
||||
void rrc_ra_problem();
|
||||
void rrc_ra_completed();
|
||||
void bcch_search(bool enabled);
|
||||
|
||||
/// stack interface
|
||||
void process_pdus();
|
||||
|
@ -149,6 +150,9 @@ private:
|
|||
|
||||
std::atomic<bool> started = {false};
|
||||
|
||||
// Boolean to determine if need to decode SI-RNTI
|
||||
bool search_bcch = false;
|
||||
|
||||
ue_rnti rntis; // thread-safe helper to store RNTIs, contention ID, etc
|
||||
bool contention_res_successful;
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ class demux_interface_harq_nr
|
|||
{
|
||||
public:
|
||||
/// Inform demux unit about a newly decoded TB.
|
||||
virtual void push_bcch(srsran::unique_byte_buffer_t pdu) = 0;
|
||||
virtual void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti) = 0;
|
||||
virtual void push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tti) = 0;
|
||||
virtual uint64_t get_received_crueid() = 0;
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace srsue {
|
|||
class rrc_nr::cell_selection_proc
|
||||
{
|
||||
public:
|
||||
enum class state_t { phy_cell_search, phy_cell_select };
|
||||
enum class state_t { phy_cell_search, phy_cell_select, sib_acquire };
|
||||
|
||||
using cell_selection_complete_ev = srsran::proc_result_t<rrc_cell_search_result_t>;
|
||||
explicit cell_selection_proc(rrc_nr& parent_);
|
||||
|
@ -33,6 +33,7 @@ public:
|
|||
srsran::proc_outcome_t step();
|
||||
srsran::proc_outcome_t react(const rrc_interface_phy_nr::cell_search_result_t& event);
|
||||
srsran::proc_outcome_t react(const rrc_interface_phy_nr::cell_select_result_t& event);
|
||||
srsran::proc_outcome_t react(const bool sib1_found);
|
||||
|
||||
void then(const cell_selection_complete_ev& proc_result) const;
|
||||
|
||||
|
|
|
@ -396,6 +396,7 @@ bool cc_worker::measure_csi()
|
|||
logger.error("PBCH-MIB: NR SFN (%d) does not match current SFN (%d)",
|
||||
mib.sfn,
|
||||
dl_slot_cfg.idx / SRSRAN_NSLOTS_PER_FRAME_NR(cfg.carrier.scs));
|
||||
dl_slot_cfg.idx = mib.sfn * SRSRAN_NSLOTS_PER_FRAME_NR(cfg.carrier.scs);
|
||||
}
|
||||
|
||||
// Log MIB information
|
||||
|
|
|
@ -38,6 +38,11 @@ void demux_nr::push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti)
|
|||
pdu_queue.push(std::move(pdu));
|
||||
}
|
||||
|
||||
void demux_nr::push_bcch(srsran::unique_byte_buffer_t pdu)
|
||||
{
|
||||
bcch_queue.push(std::move(pdu));
|
||||
}
|
||||
|
||||
/* Demultiplexing of MAC PDU associated with a Temporal C-RNTI. The PDU will
|
||||
* remain in buffer until demultiplex_pending_pdu() is called.
|
||||
* This features is provided to enable the Random Access Procedure to decide
|
||||
|
@ -55,6 +60,13 @@ void demux_nr::push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tt
|
|||
|
||||
void demux_nr::process_pdus()
|
||||
{
|
||||
// Handle first BCCH
|
||||
while (not bcch_queue.empty()) {
|
||||
srsran::unique_byte_buffer_t pdu = bcch_queue.wait_pop();
|
||||
logger.debug(pdu->msg, pdu->N_bytes, "Handling MAC BCCH PDU (%d B)", pdu->N_bytes);
|
||||
rlc->write_pdu_bcch_dlsch(pdu->msg, pdu->N_bytes);
|
||||
}
|
||||
// Then user PDUs
|
||||
while (not pdu_queue.empty()) {
|
||||
srsran::unique_byte_buffer_t pdu = pdu_queue.wait_pop();
|
||||
handle_pdu(rx_pdu, std::move(pdu));
|
||||
|
|
|
@ -229,8 +229,7 @@ void dl_harq_entity_nr::dl_harq_process_nr::tb_decoded(const mac_nr_grant_dl_t&
|
|||
|
||||
if (acked and result.payload != nullptr) {
|
||||
if (is_bcch) {
|
||||
logger.warning("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH) not implemented", grant.tbs);
|
||||
reset();
|
||||
harq_entity->demux_unit->push_bcch(std::move(result.payload));
|
||||
} else {
|
||||
if (grant.rnti == harq_entity->mac->get_temp_crnti()) {
|
||||
logger.debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI) not implemented",
|
||||
|
|
|
@ -158,8 +158,7 @@ mac_interface_phy_nr::sched_rnti_t mac_nr::get_ul_sched_rnti_nr(const uint32_t t
|
|||
|
||||
bool mac_nr::is_si_opportunity()
|
||||
{
|
||||
// TODO: ask RRC if we need SI
|
||||
return false;
|
||||
return search_bcch;
|
||||
}
|
||||
|
||||
bool mac_nr::is_paging_opportunity()
|
||||
|
@ -447,6 +446,11 @@ void mac_nr::set_contention_id(uint64_t ue_identity)
|
|||
rntis.set_contention_id(ue_identity);
|
||||
}
|
||||
|
||||
void mac_nr::bcch_search(bool enabled)
|
||||
{
|
||||
search_bcch = enabled;
|
||||
}
|
||||
|
||||
bool mac_nr::set_crnti(const uint16_t c_rnti_)
|
||||
{
|
||||
if (is_valid_crnti(c_rnti_)) {
|
||||
|
|
|
@ -391,6 +391,11 @@ void rrc_nr::set_phy_default_config()
|
|||
|
||||
void rrc_nr::handle_sib1(const sib1_s& sib1)
|
||||
{
|
||||
if (meas_cells.serving_cell().has_sib1()) {
|
||||
logger.info("SIB1 already processed");
|
||||
return;
|
||||
}
|
||||
|
||||
meas_cells.serving_cell().set_sib1(sib1);
|
||||
|
||||
logger.info("SIB1 received, CellID=%d", meas_cells.serving_cell().get_cell_id() & 0xfff);
|
||||
|
@ -486,6 +491,9 @@ void rrc_nr::handle_sib1(const sib1_s& sib1)
|
|||
logger.warning("Could not set phy config.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify cell selector of successful SIB1 reception
|
||||
cell_selector.trigger(true);
|
||||
}
|
||||
|
||||
void rrc_nr::write_pdu_pcch(srsran::unique_byte_buffer_t pdu) {}
|
||||
|
|
|
@ -384,12 +384,12 @@ proc_outcome_t rrc_nr::cell_selection_proc::init()
|
|||
return proc_outcome_t::yield;
|
||||
}
|
||||
|
||||
// Skipping SI acquisition procedure
|
||||
proc_outcome_t rrc_nr::cell_selection_proc::step()
|
||||
{
|
||||
switch (state) {
|
||||
case state_t::phy_cell_search:
|
||||
case state_t::phy_cell_select:
|
||||
case state_t::sib_acquire:
|
||||
// Waits for cell select/search to complete
|
||||
return proc_outcome_t::yield;
|
||||
}
|
||||
|
@ -400,84 +400,97 @@ proc_outcome_t rrc_nr::cell_selection_proc::step()
|
|||
proc_outcome_t
|
||||
rrc_nr::cell_selection_proc::handle_cell_search_result(const rrc_interface_phy_nr::cell_search_result_t& result)
|
||||
{
|
||||
if (result.cell_found) {
|
||||
// Convert Cell measurement in Text
|
||||
std::array<char, 512> csi_info_str = {};
|
||||
srsran_csi_meas_info_short(&result.measurements, csi_info_str.data(), (uint32_t)csi_info_str.size());
|
||||
|
||||
// Unpack MIB and convert to text
|
||||
srsran_mib_nr_t mib = {};
|
||||
std::array<char, 512> mib_info_str = {};
|
||||
if (srsran_pbch_msg_nr_mib_unpack(&result.pbch_msg, &mib) == SRSASN_SUCCESS) {
|
||||
// Convert to text
|
||||
srsran_pbch_msg_nr_mib_info(&mib, mib_info_str.data(), (uint32_t)mib_info_str.size());
|
||||
} else {
|
||||
// It could be the PBCH does not carry MIB
|
||||
strcpy(mib_info_str.data(), "No MIB found");
|
||||
}
|
||||
|
||||
// Logs the PCI, cell measurements and decoded MIB
|
||||
Info("Cell search found ARFCN=%d PCI=%d %s %s",
|
||||
result.ssb_arfcn,
|
||||
result.pci,
|
||||
csi_info_str.data(),
|
||||
mib_info_str.data());
|
||||
|
||||
// Transition to cell selection ignoring the cell search result
|
||||
state = state_t::phy_cell_select;
|
||||
|
||||
// until cell selection is done, update PHY config to take the last found PCI
|
||||
rrc_handle.phy_cfg.carrier.pci = result.pci;
|
||||
|
||||
phy_interface_rrc_nr::cell_select_args_t cs_args = {};
|
||||
cs_args.carrier = rrc_handle.phy_cfg.carrier;
|
||||
cs_args.ssb_cfg = rrc_handle.phy_cfg.get_ssb_cfg();
|
||||
|
||||
{
|
||||
// Coreset0 configuration
|
||||
srsran::phy_cfg_nr_t& phy_cfg = rrc_handle.phy_cfg;
|
||||
|
||||
// Get pointA and SSB absolute frequencies
|
||||
double pointA_abs_freq_Hz =
|
||||
phy_cfg.carrier.dl_center_frequency_hz -
|
||||
phy_cfg.carrier.nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(phy_cfg.carrier.scs) / 2;
|
||||
double ssb_abs_freq_Hz = phy_cfg.carrier.ssb_center_freq_hz;
|
||||
// Calculate integer SSB to pointA frequency offset in Hz
|
||||
uint32_t ssb_pointA_freq_offset_Hz =
|
||||
(ssb_abs_freq_Hz > pointA_abs_freq_Hz) ? (uint32_t)(ssb_abs_freq_Hz - pointA_abs_freq_Hz) : 0;
|
||||
|
||||
if (srsran_coreset_zero(phy_cfg.carrier.pci,
|
||||
ssb_pointA_freq_offset_Hz,
|
||||
phy_cfg.ssb.scs,
|
||||
phy_cfg.carrier.scs,
|
||||
6,
|
||||
&phy_cfg.pdcch.coreset[0])) {
|
||||
fprintf(stderr, "Error generating coreset0\n");
|
||||
}
|
||||
phy_cfg.pdcch.coreset_present[0] = true;
|
||||
}
|
||||
|
||||
// Until SI acquisition is implemented, provide hard-coded SIB for now
|
||||
uint8_t msg[] = {0x74, 0x81, 0x01, 0x70, 0x10, 0x40, 0x04, 0x02, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x33, 0x60, 0x38,
|
||||
0x05, 0x01, 0x00, 0x40, 0x1a, 0x00, 0x00, 0x06, 0x6c, 0x6d, 0x92, 0x21, 0xf3, 0x70, 0x40, 0x20,
|
||||
0x00, 0x00, 0x80, 0x80, 0x00, 0x41, 0x06, 0x80, 0xa0, 0x90, 0x9c, 0x20, 0x08, 0x55, 0x19, 0x40,
|
||||
0x00, 0x00, 0x33, 0xa1, 0xc6, 0xd9, 0x22, 0x40, 0x00, 0x00, 0x20, 0xb8, 0x94, 0x63, 0xc0, 0x09,
|
||||
0x28, 0x44, 0x1b, 0x7e, 0xad, 0x8e, 0x1d, 0x00, 0x9e, 0x2d, 0xa3, 0x0a};
|
||||
srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer();
|
||||
memcpy(pdu->msg, msg, sizeof(msg));
|
||||
pdu->N_bytes = sizeof(msg);
|
||||
rrc_handle.write_pdu_bcch_dlsch(std::move(pdu));
|
||||
|
||||
if (not rrc_handle.phy->start_cell_select(cs_args)) {
|
||||
Error("Could not set start cell search.");
|
||||
return proc_outcome_t::error;
|
||||
}
|
||||
return proc_outcome_t::yield;
|
||||
} else {
|
||||
if (!result.cell_found) {
|
||||
Info("Cell search did not find any cell.");
|
||||
return proc_outcome_t::error;
|
||||
}
|
||||
|
||||
return proc_outcome_t::error;
|
||||
// Convert Cell measurement in Text
|
||||
std::array<char, 512> csi_info_str = {};
|
||||
srsran_csi_meas_info_short(&result.measurements, csi_info_str.data(), (uint32_t)csi_info_str.size());
|
||||
|
||||
// Unpack MIB and convert to text
|
||||
srsran_mib_nr_t mib = {};
|
||||
std::array<char, 512> mib_info_str = {};
|
||||
if (srsran_pbch_msg_nr_mib_unpack(&result.pbch_msg, &mib) == SRSASN_SUCCESS) {
|
||||
// Convert to text
|
||||
srsran_pbch_msg_nr_mib_info(&mib, mib_info_str.data(), (uint32_t)mib_info_str.size());
|
||||
} else {
|
||||
// It could be the PBCH does not carry MIB
|
||||
strcpy(mib_info_str.data(), "No MIB found");
|
||||
Error("No MIB found\n");
|
||||
return proc_outcome_t::error;
|
||||
}
|
||||
|
||||
// Check unsupported settings
|
||||
if (mib.cell_barred) {
|
||||
Error("Cell barred");
|
||||
return proc_outcome_t::error;
|
||||
}
|
||||
if (mib.scs_common != srsran_subcarrier_spacing_15kHz) {
|
||||
Error("Unsupported SCS %s", srsran_subcarrier_spacing_to_str(mib.scs_common));
|
||||
return proc_outcome_t::error;
|
||||
}
|
||||
// TODO: calculate SSB offset
|
||||
if (mib.ssb_offset != 6) {
|
||||
Error("Unsupported SSB offset %d", mib.ssb_offset);
|
||||
return proc_outcome_t::error;
|
||||
}
|
||||
|
||||
// Logs the PCI, cell measurements and decoded MIB
|
||||
Info("Cell search found ARFCN=%d PCI=%d %s %s",
|
||||
result.ssb_arfcn,
|
||||
result.pci,
|
||||
csi_info_str.data(),
|
||||
mib_info_str.data());
|
||||
|
||||
// Apply MIB settings
|
||||
srsran::phy_cfg_nr_t& phy_cfg = rrc_handle.phy_cfg;
|
||||
phy_cfg.pdsch.typeA_pos = mib.dmrs_typeA_pos;
|
||||
phy_cfg.pdsch.scs_cfg = mib.scs_common;
|
||||
phy_cfg.carrier.pci = result.pci;
|
||||
|
||||
// Get pointA and SSB absolute frequencies
|
||||
double pointA_abs_freq_Hz = phy_cfg.carrier.dl_center_frequency_hz -
|
||||
phy_cfg.carrier.nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(phy_cfg.carrier.scs) / 2;
|
||||
double ssb_abs_freq_Hz = phy_cfg.carrier.ssb_center_freq_hz;
|
||||
// Calculate integer SSB to pointA frequency offset in Hz
|
||||
uint32_t ssb_pointA_freq_offset_Hz =
|
||||
(ssb_abs_freq_Hz > pointA_abs_freq_Hz) ? (uint32_t)(ssb_abs_freq_Hz - pointA_abs_freq_Hz) : 0;
|
||||
|
||||
// Create coreset0
|
||||
if (srsran_coreset_zero(phy_cfg.carrier.pci,
|
||||
ssb_pointA_freq_offset_Hz,
|
||||
phy_cfg.ssb.scs,
|
||||
phy_cfg.carrier.scs,
|
||||
mib.coreset0_idx,
|
||||
&phy_cfg.pdcch.coreset[0])) {
|
||||
Error("Error generating coreset0");
|
||||
return proc_outcome_t::error;
|
||||
}
|
||||
phy_cfg.pdcch.coreset_present[0] = true;
|
||||
|
||||
// Create SearchSpace0
|
||||
make_phy_search_space0_cfg(&phy_cfg.pdcch.search_space[0]);
|
||||
phy_cfg.pdcch.search_space_present[0] = true;
|
||||
|
||||
// Update PHY configuration
|
||||
if (not rrc_handle.phy->set_config(phy_cfg)) {
|
||||
Error("Setting PHY configuration");
|
||||
return proc_outcome_t::error;
|
||||
}
|
||||
|
||||
phy_interface_rrc_nr::cell_select_args_t cs_args = {};
|
||||
cs_args.carrier = rrc_handle.phy_cfg.carrier;
|
||||
cs_args.ssb_cfg = rrc_handle.phy_cfg.get_ssb_cfg();
|
||||
|
||||
// Transition to cell selection ignoring the cell search result
|
||||
state = state_t::phy_cell_select;
|
||||
if (not rrc_handle.phy->start_cell_select(cs_args)) {
|
||||
Error("Could not set start cell search.");
|
||||
return proc_outcome_t::error;
|
||||
}
|
||||
return proc_outcome_t::yield;
|
||||
}
|
||||
|
||||
proc_outcome_t rrc_nr::cell_selection_proc::react(const rrc_interface_phy_nr::cell_select_result_t& event)
|
||||
|
@ -497,7 +510,24 @@ proc_outcome_t rrc_nr::cell_selection_proc::react(const rrc_interface_phy_nr::ce
|
|||
rrc_search_result = rrc_nr::rrc_cell_search_result_t::same_cell;
|
||||
|
||||
// PHY is now camping on serving cell
|
||||
Info("Cell search completed.");
|
||||
Info("Cell selection completed. Starting SIB1 acquisition");
|
||||
|
||||
// Transition to cell selection ignoring the cell search result
|
||||
state = state_t::sib_acquire;
|
||||
rrc_handle.mac->bcch_search(true);
|
||||
return proc_outcome_t::yield;
|
||||
}
|
||||
|
||||
proc_outcome_t rrc_nr::cell_selection_proc::react(const bool sib1_found)
|
||||
{
|
||||
if (state != state_t::sib_acquire) {
|
||||
Warning("Received unexpected cell select result");
|
||||
return proc_outcome_t::yield;
|
||||
}
|
||||
|
||||
Info("SIB1 acquired successfully");
|
||||
rrc_handle.mac->bcch_search(false);
|
||||
|
||||
return proc_outcome_t::success;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ class dummy_mac : public mac_interface_rrc_nr
|
|||
int add_tag_config(const srsran::tag_cfg_nr_t& tag_cfg) { return SRSRAN_SUCCESS; }
|
||||
int set_config(const srsran::phr_cfg_nr_t& phr_cfg) { return SRSRAN_SUCCESS; }
|
||||
int remove_tag_config(const uint32_t tag_id) { return SRSRAN_SUCCESS; }
|
||||
void bcch_search(bool) {}
|
||||
|
||||
void start_ra_procedure() {}
|
||||
|
||||
|
|
Loading…
Reference in New Issue