srsue,nr: decode SIB1 based on coreset0 configuration in MIB

This commit is contained in:
Ismael Gomez 2022-03-28 22:47:50 +02:00
parent bfe69deccc
commit b3497c4a94
14 changed files with 164 additions and 82 deletions

View File

@ -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,

View File

@ -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 {

View File

@ -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 = {};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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));

View File

@ -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",

View File

@ -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_)) {

View File

@ -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) {}

View File

@ -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;
}

View File

@ -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() {}