diff --git a/lib/include/srsran/interfaces/gnb_interfaces.h b/lib/include/srsran/interfaces/gnb_interfaces.h index c061c58cc..d0c9fd902 100644 --- a/lib/include/srsran/interfaces/gnb_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_interfaces.h @@ -210,7 +210,9 @@ public: class mac_interface_phy_nr { public: - const static int MAX_GRANTS = 64; + const static int MAX_SSB = 4; + const static int MAX_GRANTS = 64; + const static int MAX_NZP_CSI_RS = 4; struct pdcch_dl_t { srsran_dci_cfg_nr_t dci_cfg = {}; @@ -227,13 +229,16 @@ public: std::array data = {}; ///< Data pointer }; + struct ssb_t { + srsran_pbch_msg_nr_t pbch_msg = {}; + }; + struct dl_sched_t { - std::array pdcch_dl; - uint32_t pdcch_dl_count = 0; - std::array pdcch_ul; - uint32_t pdcch_ul_count = 0; - std::array pdsch; - uint32_t pdsch_count = 0; + srsran::bounded_vector ssb; + srsran::bounded_vector pdcch_dl; + srsran::bounded_vector pdcch_ul; + srsran::bounded_vector pdsch; + srsran::bounded_vector nzp_csi_rs; }; struct pusch_t { @@ -242,15 +247,14 @@ public: std::array softbuffer_tx = {}; ///< Tx Softbuffer }; - struct uci_t { - srsran_uci_cfg_nr_t cfg; + struct pucch_t { + srsran_uci_cfg_nr_t uci_cfg; + srsran_pucch_nr_resource_t resource; }; struct ul_sched_t { - std::array pusch; - uint32_t pusch_count = 0; - std::array uci; - uint32_t uci_count; + srsran::bounded_vector pusch; + srsran::bounded_vector pucch; }; virtual int slot_indication(const srsran_slot_cfg_t& slot_cfg) = 0; @@ -267,7 +271,6 @@ public: srsran::unique_byte_buffer_t tb; }; - virtual int sf_indication(const uint32_t tti) = 0; virtual int rx_data_indication(rx_data_ind_t& grant) = 0; }; diff --git a/lib/src/common/basic_vnf.cc b/lib/src/common/basic_vnf.cc index 223d9a9dc..be8a609e9 100644 --- a/lib/src/common/basic_vnf.cc +++ b/lib/src/common/basic_vnf.cc @@ -155,7 +155,9 @@ int srsran_basic_vnf::handle_sf_ind(basic_vnf_api::sf_ind_msg_t* msg) last_sf_indication_time = msg->t1; if (m_gnb_stack != nullptr) { - m_gnb_stack->sf_indication(msg->tti); + srsran_slot_cfg_t slot_cfg = {}; + slot_cfg.idx = msg->tti; + m_gnb_stack->slot_indication(slot_cfg); } else if (m_ue_stack != nullptr) { m_ue_stack->sf_indication(msg->tti); } else { diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index 549791e32..328348e4c 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -59,12 +59,11 @@ public: bool start_service_request() override { return true; }; // PHY->MAC interface - int sf_indication(const uint32_t tti) override; int rx_data_indication(rx_data_ind_t& grant) override; // Temporary GW interface - void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu); - bool has_active_radio_bearer(uint32_t eps_bearer_id); + void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu) override; + bool has_active_radio_bearer(uint32_t eps_bearer_id) override; bool switch_on(); void run_tti(uint32_t tti); diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index c47a4572e..9bb1fa0bf 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -132,14 +132,12 @@ bool slot_worker::work_ul() } // Decode PUCCH - for (uint32_t i = 0; i < ul_sched.uci_count; i++) { - const stack_interface_phy_nr::uci_t& uci = ul_sched.uci[i]; + for (stack_interface_phy_nr::pucch_t& pucch : ul_sched.pucch) { // ... } // Decode PUSCH - for (uint32_t i = 0; i < ul_sched.pusch_count; i++) { - const stack_interface_phy_nr::pusch_t& pusch = ul_sched.pusch[i]; + for (stack_interface_phy_nr::pusch_t& pusch : ul_sched.pusch) { // ... } @@ -148,17 +146,20 @@ bool slot_worker::work_ul() bool slot_worker::work_dl() { + // Retrieve Scheduling for the current processing DL slot stack_interface_phy_nr::dl_sched_t dl_sched = {}; if (stack.get_dl_sched(ul_slot_cfg, dl_sched) < SRSRAN_SUCCESS) { logger.error("Error retrieving DL scheduling"); return false; } - // Encode PDCCH for DL transmissions - for (uint32_t i = 0; i < dl_sched.pdcch_dl_count; i++) { - // Select PDCCH from scheduler result - const stack_interface_phy_nr::pdcch_dl_t& pdcch = dl_sched.pdcch_dl[i]; + if (srsran_enb_dl_nr_base_zero(&gnb_dl) < SRSRAN_SUCCESS) { + logger.error("Error zeroeing RE grid"); + return false; + } + // Encode PDCCH for DL transmissions + for (const stack_interface_phy_nr::pdcch_dl_t& pdcch : dl_sched.pdcch_dl) { // Set PDCCH configuration, including DCI dedicated if (srsran_enb_dl_nr_set_pdcch_config(&gnb_dl, &pdcch_cfg, &pdcch.dci_cfg) < SRSRAN_SUCCESS) { logger.error("PDCCH: Error setting DL configuration"); @@ -180,10 +181,7 @@ bool slot_worker::work_dl() } // Encode PDCCH for UL transmissions - for (uint32_t i = 0; i < dl_sched.pdcch_ul_count; i++) { - // Select PDCCH from scheduler result - const stack_interface_phy_nr::pdcch_ul_t& pdcch = dl_sched.pdcch_ul[i]; - + for (const stack_interface_phy_nr::pdcch_ul_t& pdcch : dl_sched.pdcch_ul) { // Set PDCCH configuration, including DCI dedicated if (srsran_enb_dl_nr_set_pdcch_config(&gnb_dl, &pdcch_cfg, &pdcch.dci_cfg) < SRSRAN_SUCCESS) { logger.error("PDCCH: Error setting DL configuration"); @@ -205,10 +203,7 @@ bool slot_worker::work_dl() } // Encode PDSCH - for (uint32_t i = 0; i < dl_sched.pdsch_count; i++) { - // Select PDSCH from scheduler result - stack_interface_phy_nr::pdsch_t& pdsch = dl_sched.pdsch[i]; - + for (stack_interface_phy_nr::pdsch_t& pdsch : dl_sched.pdsch) { // Put PDSCH message if (srsran_enb_dl_nr_pdsch_put(&gnb_dl, &dl_slot_cfg, &pdsch.sch, pdsch.data.data()) < SRSRAN_SUCCESS) { logger.error("PDSCH: Error putting DL message"); @@ -223,16 +218,26 @@ bool slot_worker::work_dl() } } + // Put NZP-CSI-RS + for (srsran_csi_rs_nzp_resource_t& pdsch : dl_sched.nzp_csi_rs) { + // ... + } + // Generate baseband signal srsran_enb_dl_nr_gen_signal(&gnb_dl); + // Add SSB to the baseband signal + for (const stack_interface_phy_nr::ssb_t& ssb : dl_sched.ssb) { + // ... + } + return true; } void slot_worker::work_imp() { // Inform Scheduler about new slot - stack.sf_indication(dl_slot_cfg.idx); + stack.slot_indication(dl_slot_cfg); // Get Transmission buffers srsran::rf_buffer_t tx_rf_buffer = {}; diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index cafe2e7c3..54a25b4bc 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -162,11 +162,6 @@ bool gnb_stack_nr::get_metrics(srsenb::stack_metrics_t* metrics) return true; } -int gnb_stack_nr::sf_indication(const uint32_t tti) -{ - return m_mac->sf_indication(tti); -} - int gnb_stack_nr::rx_data_indication(rx_data_ind_t& grant) { return m_mac->rx_data_indication(grant); diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 66ba30c0f..f03dec542 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -176,15 +176,15 @@ void mac_nr::get_dl_config(const uint32_t tti, tx_request.tti = tti; } -int mac_nr::sf_indication(const uint32_t tti) +int mac_nr::slot_indication(const srsran_slot_cfg_t& slot_cfg) { phy_interface_stack_nr::dl_config_request_t config_request = {}; phy_interface_stack_nr::tx_request_t tx_request = {}; // step MAC TTI - logger.set_context(tti); + logger.set_context(slot_cfg.idx); - get_dl_config(tti, config_request, tx_request); + get_dl_config(slot_cfg.idx, config_request, tx_request); // send DL_CONFIG.request phy_h->dl_config_request(config_request); @@ -267,10 +267,6 @@ int mac_nr::cell_cfg(srsenb::sched_interface::cell_cfg_t* cell_cfg) return SRSRAN_SUCCESS; } -int mac_nr::slot_indication(const srsran_slot_cfg_t& slot_cfg) -{ - return 0; -} int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) { diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index 4536ac999..8162dcac4 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -166,7 +166,6 @@ public: ~gnb_dummy_stack() { srsran_random_free(random_gen); } bool is_valid() const { return valid; } - int sf_indication(const uint32_t tti) override { return 0; } int rx_data_indication(rx_data_ind_t& grant) override { return 0; } int slot_indication(const srsran_slot_cfg_t& slot_cfg) override { return 0; } @@ -178,9 +177,9 @@ public: return SRSRAN_SUCCESS; } - // Select PDCCH and PDSCH from scheduling results - pdcch_dl_t& pdcch = dl_sched.pdcch_dl[0]; - pdsch_t& pdsch = dl_sched.pdsch[0]; + // Instantiate PDCCH and PDSCH + pdcch_dl_t pdcch = {}; + pdsch_t pdsch = {}; // Select grant and set data pdsch.data[0] = tx_harq_proc[slot_cfg.idx].data.data(); @@ -188,9 +187,6 @@ public: // Second TB is not used pdsch.data[1] = nullptr; - // Generate random data - srsran_random_byte_vector(random_gen, pdsch.data[0], SRSRAN_LDPC_MAX_LEN_CB * SRSRAN_SCH_NR_MAX_NOF_CB_LDPC / 8); - // Fill DCI configuration pdcch.dci_cfg = phy_cfg.get_dci_cfg(); @@ -213,10 +209,6 @@ public: dci.pucch_resource = 0; dci.harq_feedback = dl_data_to_ul_ack[TTI_TX(slot_cfg.idx)]; - // It currently support only one grant - dl_sched.pdcch_dl_count = 1; - dl_sched.pdsch_count = 1; - // Create PDSCH configuration if (srsran_ra_dl_dci_to_grant_nr(&phy_cfg.carrier, &slot_cfg, &phy_cfg.pdsch, &dci, &pdsch.sch, &pdsch.sch.grant) < SRSRAN_SUCCESS) { @@ -224,12 +216,19 @@ public: return SRSRAN_ERROR; } + // Generate random data + srsran_random_byte_vector(random_gen, pdsch.data[0], pdsch.sch.grant.tb[0].tbs / 8); + // Set softbuffer pdsch.sch.grant.tb[0].softbuffer.tx = &tx_harq_proc[slot_cfg.idx].softbuffer; // Reset Tx softbuffer always srsran_softbuffer_tx_reset(pdsch.sch.grant.tb[0].softbuffer.tx); + // Push scheduling results + dl_sched.pdcch_dl.push_back(pdcch); + dl_sched.pdsch.push_back(pdsch); + return SRSRAN_SUCCESS; }