Add enb MAC procedures for PDCCH orders.

master
Fabian Eckermann 3 years ago committed by Andre Puschmann
parent f228491e1d
commit 74a289976a

@ -110,6 +110,16 @@ private:
uint16_t allocate_ue(uint32_t enb_cc_idx); uint16_t allocate_ue(uint32_t enb_cc_idx);
bool is_valid_rnti_unprotected(uint16_t rnti); bool is_valid_rnti_unprotected(uint16_t rnti);
/* helper function for PDCCH orders */
/**
* @brief Checks if the current RACH is a RACH triggered by a PDCCH order.
*
* @param[in] preamble_idx RACH preamble idx
* @param rnti is the rnti where the crnti of the RACH is written
* @return true if this is a RACH triggered by a PDCCH order, otherwise it returns false
*/
bool is_pending_pdcch_order_prach(const uint32_t preamble_idx, uint16_t& rnti);
srslog::basic_logger& logger; srslog::basic_logger& logger;
// We use a rwlock in MAC to allow multiple workers to access MAC simultaneously. No conflicts will happen since // We use a rwlock in MAC to allow multiple workers to access MAC simultaneously. No conflicts will happen since
@ -181,6 +191,9 @@ private:
// Number of rach preambles detected for a cc. // Number of rach preambles detected for a cc.
std::vector<uint32_t> detected_rachs; std::vector<uint32_t> detected_rachs;
// PDCCH order
std::vector<sched_interface::dl_sched_po_info_t> pending_po_prachs = {};
// Softbuffer pool // Softbuffer pool
std::unique_ptr<srsran::obj_pool_itf<ue_cc_softbuffers> > softbuffer_pool; std::unique_ptr<srsran::obj_pool_itf<ue_cc_softbuffers> > softbuffer_pool;
}; };

@ -71,6 +71,8 @@ public:
int dl_sched(uint32_t tti, uint32_t enb_cc_idx, dl_sched_res_t& sched_result) final; int dl_sched(uint32_t tti, uint32_t enb_cc_idx, dl_sched_res_t& sched_result) final;
int ul_sched(uint32_t tti, uint32_t enb_cc_idx, ul_sched_res_t& sched_result) final; int ul_sched(uint32_t tti, uint32_t enb_cc_idx, ul_sched_res_t& sched_result) final;
int set_pdcch_order(uint32_t enb_cc_idx, dl_sched_po_info_t pdcch_order_info) final;
/* Custom functions /* Custom functions
*/ */
void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) final; void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) final;

@ -36,6 +36,7 @@ public:
void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs); void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs);
const cc_sched_result& generate_tti_result(srsran::tti_point tti_rx); const cc_sched_result& generate_tti_result(srsran::tti_point tti_rx);
int dl_rach_info(dl_sched_rar_info_t rar_info); int dl_rach_info(dl_sched_rar_info_t rar_info);
int pdcch_order_info(dl_sched_po_info_t pdcch_order_info);
// getters // getters
const ra_sched* get_ra_sched() const { return ra_sched_ptr.get(); } const ra_sched* get_ra_sched() const { return ra_sched_ptr.get(); }
@ -49,6 +50,8 @@ private:
int alloc_ul_users(sf_sched* tti_sched); int alloc_ul_users(sf_sched* tti_sched);
//! Get sf_sched for a given TTI //! Get sf_sched for a given TTI
sf_sched* get_sf_sched(srsran::tti_point tti_rx); sf_sched* get_sf_sched(srsran::tti_point tti_rx);
//! Schedule PDCCH orders
void pdcch_order_sched(sf_sched* tti_sched);
// args // args
const sched_cell_params_t* cc_cfg = nullptr; const sched_cell_params_t* cc_cfg = nullptr;
@ -68,6 +71,11 @@ private:
std::unique_ptr<bc_sched> bc_sched_ptr; std::unique_ptr<bc_sched> bc_sched_ptr;
std::unique_ptr<ra_sched> ra_sched_ptr; std::unique_ptr<ra_sched> ra_sched_ptr;
std::unique_ptr<sched_base> sched_algo; std::unique_ptr<sched_base> sched_algo;
// pending pdcch orders
std::vector<dl_sched_po_info_t> pending_pdcch_orders;
uint32_t po_aggr_level = 2;
}; };
//! Broadcast (SIB + paging) scheduler //! Broadcast (SIB + paging) scheduler

@ -141,6 +141,9 @@ public:
struct bc_alloc_t : public ctrl_alloc_t { struct bc_alloc_t : public ctrl_alloc_t {
sched_interface::dl_sched_bc_t bc_grant; sched_interface::dl_sched_bc_t bc_grant;
}; };
struct po_alloc_t : public ctrl_alloc_t {
sched_interface::dl_sched_po_t po_grant;
};
struct dl_alloc_t { struct dl_alloc_t {
size_t dci_idx; size_t dci_idx;
uint16_t rnti; uint16_t rnti;
@ -174,6 +177,8 @@ public:
alloc_result alloc_sib(uint32_t aggr_lvl, uint32_t sib_idx, uint32_t sib_ntx, rbg_interval rbgs); alloc_result alloc_sib(uint32_t aggr_lvl, uint32_t sib_idx, uint32_t sib_ntx, rbg_interval rbgs);
alloc_result alloc_paging(uint32_t aggr_lvl, uint32_t paging_payload, rbg_interval rbgs); alloc_result alloc_paging(uint32_t aggr_lvl, uint32_t paging_payload, rbg_interval rbgs);
alloc_result alloc_rar(uint32_t aggr_lvl, const pending_rar_t& rar_grant, rbg_interval rbgs, uint32_t nof_grants); alloc_result alloc_rar(uint32_t aggr_lvl, const pending_rar_t& rar_grant, rbg_interval rbgs, uint32_t nof_grants);
alloc_result
alloc_pdcch_order(const sched_interface::dl_sched_po_info_t& po_cfg, uint32_t aggr_lvl, rbg_interval rbgs);
bool reserve_dl_rbgs(uint32_t rbg_start, uint32_t rbg_end) { return tti_alloc.reserve_dl_rbgs(rbg_start, rbg_end); } bool reserve_dl_rbgs(uint32_t rbg_start, uint32_t rbg_end) { return tti_alloc.reserve_dl_rbgs(rbg_start, rbg_end); }
// UL alloc methods // UL alloc methods
@ -223,6 +228,7 @@ private:
srsran::bounded_vector<bc_alloc_t, sched_interface::MAX_BC_LIST> bc_allocs; srsran::bounded_vector<bc_alloc_t, sched_interface::MAX_BC_LIST> bc_allocs;
srsran::bounded_vector<rar_alloc_t, sched_interface::MAX_RAR_LIST> rar_allocs; srsran::bounded_vector<rar_alloc_t, sched_interface::MAX_RAR_LIST> rar_allocs;
srsran::bounded_vector<po_alloc_t, sched_interface::MAX_PO_LIST> po_allocs;
srsran::bounded_vector<dl_alloc_t, sched_interface::MAX_DATA_LIST> data_allocs; srsran::bounded_vector<dl_alloc_t, sched_interface::MAX_DATA_LIST> data_allocs;
srsran::bounded_vector<ul_alloc_t, sched_interface::MAX_DATA_LIST> ul_data_allocs; srsran::bounded_vector<ul_alloc_t, sched_interface::MAX_DATA_LIST> ul_data_allocs;
uint32_t last_msg3_prb = 0, max_msg3_prb = 0; uint32_t last_msg3_prb = 0, max_msg3_prb = 0;

@ -37,6 +37,7 @@ public:
const static int MAX_DATA_LIST = 32; const static int MAX_DATA_LIST = 32;
const static int MAX_RAR_LIST = 8; const static int MAX_RAR_LIST = 8;
const static int MAX_BC_LIST = 8; const static int MAX_BC_LIST = 8;
const static int MAX_PO_LIST = 8;
const static int MAX_RLC_PDU_LIST = 8; const static int MAX_RLC_PDU_LIST = 8;
const static int MAX_PHICH_LIST = 8; const static int MAX_PHICH_LIST = 8;
@ -215,20 +216,31 @@ public:
typedef struct { typedef struct {
srsran_dci_dl_t dci; srsran_dci_dl_t dci;
enum bc_type { BCCH, PCCH } type; enum bc_type { BCCH, PCCH } type;
uint32_t index; uint32_t index;
uint32_t tbs; uint32_t tbs;
} dl_sched_bc_t; } dl_sched_bc_t;
struct dl_sched_po_info_t {
uint32_t preamble_idx;
uint32_t prach_mask_idx;
uint16_t crnti;
};
typedef struct {
srsran_dci_dl_t dci;
uint32_t tbs;
uint16_t crnti;
uint32_t preamble_idx;
uint32_t prach_mask_idx;
} dl_sched_po_t;
struct dl_sched_res_t { struct dl_sched_res_t {
uint32_t cfi; uint32_t cfi;
srsran::bounded_vector<dl_sched_data_t, MAX_DATA_LIST> data; srsran::bounded_vector<dl_sched_data_t, MAX_DATA_LIST> data;
srsran::bounded_vector<dl_sched_rar_t, MAX_RAR_LIST> rar; srsran::bounded_vector<dl_sched_rar_t, MAX_RAR_LIST> rar;
srsran::bounded_vector<dl_sched_bc_t, MAX_BC_LIST> bc; srsran::bounded_vector<dl_sched_bc_t, MAX_BC_LIST> bc;
srsran::bounded_vector<dl_sched_po_t, MAX_PO_LIST> po;
}; };
typedef struct { typedef struct {
@ -301,6 +313,9 @@ public:
virtual int dl_sched(uint32_t tti, uint32_t enb_cc_idx, dl_sched_res_t& sched_result) = 0; virtual int dl_sched(uint32_t tti, uint32_t enb_cc_idx, dl_sched_res_t& sched_result) = 0;
virtual int ul_sched(uint32_t tti, uint32_t enb_cc_idx, ul_sched_res_t& sched_result) = 0; virtual int ul_sched(uint32_t tti, uint32_t enb_cc_idx, ul_sched_res_t& sched_result) = 0;
/* PDCCH order */
virtual int set_pdcch_order(uint32_t enb_cc_idx, dl_sched_po_info_t pdcch_order_info) = 0;
/* Custom */ /* Custom */
virtual void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) = 0; virtual void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) = 0;
virtual std::array<int, SRSRAN_MAX_CARRIERS> get_enb_ue_cc_map(uint16_t rnti) = 0; virtual std::array<int, SRSRAN_MAX_CARRIERS> get_enb_ue_cc_map(uint16_t rnti) = 0;

@ -82,10 +82,11 @@ public:
}; };
/// Type of Allocation stored in PDSCH/PUSCH /// Type of Allocation stored in PDSCH/PUSCH
enum class alloc_type_t { DL_BC, DL_PCCH, DL_RAR, DL_DATA, UL_DATA }; enum class alloc_type_t { DL_BC, DL_PCCH, DL_RAR, DL_PDCCH_ORDER, DL_DATA, UL_DATA };
inline bool is_dl_ctrl_alloc(alloc_type_t a) inline bool is_dl_ctrl_alloc(alloc_type_t a)
{ {
return a == alloc_type_t::DL_BC or a == alloc_type_t::DL_PCCH or a == alloc_type_t::DL_RAR; return a == alloc_type_t::DL_BC or a == alloc_type_t::DL_PCCH or a == alloc_type_t::DL_RAR or
a == alloc_type_t::DL_PDCCH_ORDER;
} }
} // namespace srsenb } // namespace srsenb

@ -104,6 +104,11 @@ bool generate_rar_dci(sched_interface::dl_sched_rar_t& rar,
const sched_cell_params_t& cell_params, const sched_cell_params_t& cell_params,
uint32_t current_cfi); uint32_t current_cfi);
void generate_pdcch_order_dci(sched_interface::dl_sched_po_t& pdcch_order,
tti_point tti_tx_dl,
const sched_cell_params_t& cell_params,
uint32_t current_cfi);
void log_broadcast_allocation(const sched_interface::dl_sched_bc_t& bc, void log_broadcast_allocation(const sched_interface::dl_sched_bc_t& bc,
rbg_interval rbg_range, rbg_interval rbg_range,
const sched_cell_params_t& cell_params); const sched_cell_params_t& cell_params);
@ -114,6 +119,10 @@ void log_rar_allocation(const sched_interface::dl_sched_rar_t& rar,
void log_rar_allocation(const sched_interface::dl_sched_rar_t& rar, rbg_interval rbg_range); void log_rar_allocation(const sched_interface::dl_sched_rar_t& rar, rbg_interval rbg_range);
void log_po_allocation(const sched_interface::dl_sched_po_t& pdcch_order,
rbg_interval rbg_range,
const sched_cell_params_t& cell_params);
} // namespace srsenb } // namespace srsenb
#endif // SRSRAN_SCHED_DCI_H #endif // SRSRAN_SCHED_DCI_H

@ -516,6 +516,21 @@ uint16_t mac::allocate_ue(uint32_t enb_cc_idx)
return rnti; return rnti;
} }
bool mac::is_pending_pdcch_order_prach(const uint32_t preamble_idx, uint16_t& rnti)
{
for (auto it = pending_po_prachs.begin(); it != pending_po_prachs.end();) {
auto& pending_po_prach = *it;
if (pending_po_prach.preamble_idx == preamble_idx) {
rnti = pending_po_prach.crnti;
// delete pending PDCCH PRACH from vector
it = pending_po_prachs.erase(it);
return true;
}
++it;
}
return false;
}
uint16_t mac::reserve_new_crnti(const sched_interface::ue_cfg_t& uecfg) uint16_t mac::reserve_new_crnti(const sched_interface::ue_cfg_t& uecfg)
{ {
uint16_t rnti = allocate_ue(uecfg.supported_cc_list[0].enb_cc_idx); uint16_t rnti = allocate_ue(uecfg.supported_cc_list[0].enb_cc_idx);
@ -537,9 +552,14 @@ void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx
auto rach_tprof_meas = rach_tprof.start(); auto rach_tprof_meas = rach_tprof.start();
stack_task_queue.push([this, tti, enb_cc_idx, preamble_idx, time_adv, rach_tprof_meas]() mutable { stack_task_queue.push([this, tti, enb_cc_idx, preamble_idx, time_adv, rach_tprof_meas]() mutable {
uint16_t rnti = allocate_ue(enb_cc_idx); uint16_t rnti = 0;
if (rnti == SRSRAN_INVALID_RNTI) { // check if this is a PRACH from a PDCCH order
return; bool is_po_prach = is_pending_pdcch_order_prach(preamble_idx, rnti);
if (!is_po_prach) {
rnti = allocate_ue(enb_cc_idx);
if (rnti == SRSRAN_INVALID_RNTI) {
return;
}
} }
rach_tprof_meas.defer_stop(); rach_tprof_meas.defer_stop();
@ -554,21 +574,24 @@ void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx
// Log this event. // Log this event.
++detected_rachs[enb_cc_idx]; ++detected_rachs[enb_cc_idx];
// Add new user to the scheduler so that it can RX/TX SRB0 // If this is a PRACH from a PDCCH order, the user already exists
sched_interface::ue_cfg_t uecfg = {}; if (not is_po_prach) {
uecfg.supported_cc_list.emplace_back(); // Add new user to the scheduler so that it can RX/TX SRB0
uecfg.supported_cc_list.back().active = true; sched_interface::ue_cfg_t uecfg = {};
uecfg.supported_cc_list.back().enb_cc_idx = enb_cc_idx; uecfg.supported_cc_list.emplace_back();
uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; uecfg.supported_cc_list.back().active = true;
uecfg.supported_cc_list[0].dl_cfg.tm = SRSRAN_TM1; uecfg.supported_cc_list.back().enb_cc_idx = enb_cc_idx;
if (ue_cfg(rnti, &uecfg) != SRSRAN_SUCCESS) { uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH;
return; uecfg.supported_cc_list[0].dl_cfg.tm = SRSRAN_TM1;
} if (ue_cfg(rnti, &uecfg) != SRSRAN_SUCCESS) {
return;
}
// Register new user in RRC // Register new user in RRC
if (rrc_h->add_user(rnti, uecfg) == SRSRAN_ERROR) { if (rrc_h->add_user(rnti, uecfg) == SRSRAN_ERROR) {
ue_rem(rnti); ue_rem(rnti);
return; return;
}
} }
// Trigger scheduler RACH // Trigger scheduler RACH
@ -579,14 +602,16 @@ void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx
return (enb_cc_idx < cell_config.size()) ? cell_config[enb_cc_idx].cell.id : 0; return (enb_cc_idx < cell_config.size()) ? cell_config[enb_cc_idx].cell.id : 0;
}; };
uint32_t pci = get_pci(); uint32_t pci = get_pci();
logger.info("RACH: tti=%d, cc=%d, pci=%d, preamble=%d, offset=%d, temp_crnti=0x%x", logger.info("%sRACH: tti=%d, cc=%d, pci=%d, preamble=%d, offset=%d, temp_crnti=0x%x",
(is_po_prach) ? "PDCCH order " : "",
tti, tti,
enb_cc_idx, enb_cc_idx,
pci, pci,
preamble_idx, preamble_idx,
time_adv, time_adv,
rnti); rnti);
srsran::console("RACH: tti=%d, cc=%d, pci=%d, preamble=%d, offset=%d, temp_crnti=0x%x\n", srsran::console("%sRACH: tti=%d, cc=%d, pci=%d, preamble=%d, offset=%d, temp_crnti=0x%x\n",
(is_po_prach) ? "PDCCH order " : "",
tti, tti,
enb_cc_idx, enb_cc_idx,
pci, pci,
@ -749,6 +774,21 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list)
n++; n++;
} }
// Copy PDCCH order grants
for (uint32_t i = 0; i < sched_result.po.size(); i++) {
// Copy dci info
dl_sched_res->pdsch[n].dci = sched_result.po[i].dci;
if (pcap) {
pcap->write_dl_pch(dl_sched_res->pdsch[n].data[0], sched_result.po[i].tbs, true, tti_tx_dl, enb_cc_idx);
}
if (pcap_net) {
pcap_net->write_dl_pch(dl_sched_res->pdsch[n].data[0], sched_result.po[i].tbs, true, tti_tx_dl, enb_cc_idx);
}
n++;
}
dl_sched_res->nof_grants = n; dl_sched_res->nof_grants = n;
// Number of CCH symbols // Number of CCH symbols
@ -829,7 +869,6 @@ int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res
ue_db[SRSRAN_MRNTI]->metrics_tx(true, mcs.tbs); ue_db[SRSRAN_MRNTI]->metrics_tx(true, mcs.tbs);
dl_sched_res->pdsch[0].data[0] = dl_sched_res->pdsch[0].data[0] =
ue_db[SRSRAN_MRNTI]->generate_mch_pdu(tti % SRSRAN_FDD_NOF_HARQ, mch, mch.num_mtch_sched + 1, mcs.tbs / 8); ue_db[SRSRAN_MRNTI]->generate_mch_pdu(tti % SRSRAN_FDD_NOF_HARQ, mch, mch.num_mtch_sched + 1, mcs.tbs / 8);
} else { } else {
uint32_t current_lcid = 1; uint32_t current_lcid = 1;
uint32_t mtch_index = 0; uint32_t mtch_index = 0;
@ -965,7 +1004,6 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list)
} else { } else {
logger.warning("Invalid UL scheduling result. User 0x%x does not exist", rnti); logger.warning("Invalid UL scheduling result. User 0x%x does not exist", rnti);
} }
} else { } else {
logger.warning("Grant %d for rnti=0x%x has zero TBS", i, sched_result.pusch[i].dci.rnti); logger.warning("Grant %d for rnti=0x%x has zero TBS", i, sched_result.pusch[i].dci.rnti);
} }

@ -292,6 +292,12 @@ std::array<int, SRSRAN_MAX_CARRIERS> sched::get_enb_ue_activ_cc_map(uint16_t rnt
return ret; return ret;
} }
int sched::set_pdcch_order(uint32_t enb_cc_idx, dl_sched_po_info_t pdcch_order_info)
{
std::lock_guard<std::mutex> lock(sched_mutex);
return carrier_schedulers[enb_cc_idx]->pdcch_order_info(pdcch_order_info);
}
/******************************************************* /*******************************************************
* *
* Main sched functions * Main sched functions

@ -340,6 +340,7 @@ void sched::carrier_sched::reset()
{ {
ra_sched_ptr.reset(); ra_sched_ptr.reset();
bc_sched_ptr.reset(); bc_sched_ptr.reset();
pending_pdcch_orders.clear();
} }
void sched::carrier_sched::carrier_cfg(const sched_cell_params_t& cell_params_) void sched::carrier_sched::carrier_cfg(const sched_cell_params_t& cell_params_)
@ -402,6 +403,9 @@ const cc_sched_result& sched::carrier_sched::generate_tti_result(tti_point tti_r
/* Schedule Msg3 */ /* Schedule Msg3 */
sf_sched* sf_msg3_sched = get_sf_sched(tti_rx + MSG3_DELAY_MS); sf_sched* sf_msg3_sched = get_sf_sched(tti_rx + MSG3_DELAY_MS);
ra_sched_ptr->ul_sched(tti_sched, sf_msg3_sched); ra_sched_ptr->ul_sched(tti_sched, sf_msg3_sched);
/* Schedule PDCCH orders */
pdcch_order_sched(tti_sched);
} }
/* Prioritize PDCCH scheduling for DL and UL data in a RoundRobin fashion */ /* Prioritize PDCCH scheduling for DL and UL data in a RoundRobin fashion */
@ -481,4 +485,38 @@ int sched::carrier_sched::dl_rach_info(dl_sched_rar_info_t rar_info)
return ra_sched_ptr->dl_rach_info(rar_info); return ra_sched_ptr->dl_rach_info(rar_info);
} }
int sched::carrier_sched::pdcch_order_info(dl_sched_po_info_t pdcch_order_info)
{
logger.info("SCHED: New PDCCH order preamble=%d, prach_mask_idx=%d crnti=0x%x",
pdcch_order_info.preamble_idx,
pdcch_order_info.prach_mask_idx,
pdcch_order_info.crnti);
// create new PDCCH order
pending_pdcch_orders.push_back(pdcch_order_info);
return SRSRAN_SUCCESS;
}
void sched::carrier_sched::pdcch_order_sched(sf_sched* tti_sched)
{
for (auto it = pending_pdcch_orders.begin(); it != pending_pdcch_orders.end();) {
auto& pending_pdcch_order = *it;
alloc_result ret = alloc_result::no_sch_space;
rbg_interval rbg_interv = find_empty_rbg_interval(1, tti_sched->get_dl_mask());
if (rbg_interv.length() == 1) {
ret = tti_sched->alloc_pdcch_order(pending_pdcch_order, po_aggr_level, rbg_interv);
}
if (ret == alloc_result::success) {
it = pending_pdcch_orders.erase(it);
} else {
logger.warning("SCHED: Could not allocate PDCCH order, cause=%s", to_string(ret));
++it;
}
}
}
} // namespace srsenb } // namespace srsenb

@ -159,7 +159,7 @@ alloc_result sf_grid_t::alloc_dl(uint32_t aggr_idx,
alloc_result sf_grid_t::alloc_dl_ctrl(uint32_t aggr_idx, rbg_interval rbg_range, alloc_type_t alloc_type) alloc_result sf_grid_t::alloc_dl_ctrl(uint32_t aggr_idx, rbg_interval rbg_range, alloc_type_t alloc_type)
{ {
if (alloc_type != alloc_type_t::DL_RAR and alloc_type != alloc_type_t::DL_BC and if (alloc_type != alloc_type_t::DL_RAR and alloc_type != alloc_type_t::DL_BC and
alloc_type != alloc_type_t::DL_PCCH) { alloc_type != alloc_type_t::DL_PCCH and alloc_type != alloc_type_t::DL_PDCCH_ORDER) {
logger.error("SCHED: DL control allocations must be RAR/BC/PDCCH"); logger.error("SCHED: DL control allocations must be RAR/BC/PDCCH");
return alloc_result::other_cause; return alloc_result::other_cause;
} }
@ -316,6 +316,7 @@ void sf_sched::new_tti(tti_point tti_rx_, sf_sched_result* cc_results_)
// reset internal state // reset internal state
bc_allocs.clear(); bc_allocs.clear();
rar_allocs.clear(); rar_allocs.clear();
po_allocs.clear();
data_allocs.clear(); data_allocs.clear();
ul_data_allocs.clear(); ul_data_allocs.clear();
@ -443,6 +444,40 @@ alloc_result sf_sched::alloc_rar(uint32_t aggr_lvl, const pending_rar_t& rar, rb
return ret; return ret;
} }
alloc_result
sf_sched::alloc_pdcch_order(const sched_interface::dl_sched_po_info_t& po_cfg, uint32_t aggr_lvl, rbg_interval rbgs)
{
if (po_allocs.full()) {
logger.warning("SCHED: Maximum number of PDCCH order allocations per TTI reached.");
return alloc_result::no_grant_space;
}
uint32_t buf_pdcch_order = 7; // TODO get actual size
// Allocate RBGs and PDCCH
alloc_result ret = tti_alloc.alloc_dl_ctrl(aggr_lvl, rbgs, alloc_type_t::DL_PDCCH_ORDER);
if (ret != alloc_result::success) {
return ret;
}
po_alloc_t po_alloc;
po_alloc.po_grant.crnti = po_cfg.crnti;
po_alloc.po_grant.preamble_idx = po_cfg.preamble_idx;
po_alloc.po_grant.prach_mask_idx = po_cfg.prach_mask_idx;
po_alloc.po_grant.tbs = buf_pdcch_order;
// Generate DCI for PDCCH order message
generate_pdcch_order_dci(po_alloc.po_grant, get_tti_tx_dl(), *cc_cfg, tti_alloc.get_cfi());
// Allocation Successful
po_alloc.dci_idx = tti_alloc.get_pdcch_grid().nof_allocs() - 1;
po_alloc.rbg_range = rbgs;
po_alloc.req_bytes = buf_pdcch_order;
po_allocs.push_back(po_alloc);
return alloc_result::success;
}
bool is_periodic_cqi_expected(const sched_interface::ue_cfg_t& ue_cfg, tti_point tti_tx_ul) bool is_periodic_cqi_expected(const sched_interface::ue_cfg_t& ue_cfg, tti_point tti_tx_ul)
{ {
for (const sched_interface::ue_cfg_t::cc_cfg_t& cc : ue_cfg.supported_cc_list) { for (const sched_interface::ue_cfg_t::cc_cfg_t& cc : ue_cfg.supported_cc_list) {
@ -942,6 +977,12 @@ void sf_sched::generate_sched_results(sched_ue_list& ue_db)
log_rar_allocation(cc_result->dl_sched_result.rar.back(), rar_alloc.alloc_data.rbg_range); log_rar_allocation(cc_result->dl_sched_result.rar.back(), rar_alloc.alloc_data.rbg_range);
} }
for (const auto& po_alloc : po_allocs) {
cc_result->dl_sched_result.po.emplace_back(po_alloc.po_grant);
cc_result->dl_sched_result.po.back().dci.location = dci_result[po_alloc.dci_idx]->dci_pos;
log_po_allocation(cc_result->dl_sched_result.po.back(), po_alloc.rbg_range, *cc_cfg);
}
set_dl_data_sched_result(dci_result, &cc_result->dl_sched_result, ue_db); set_dl_data_sched_result(dci_result, &cc_result->dl_sched_result, ue_db);
set_ul_sched_result(dci_result, &cc_result->ul_sched_result, ue_db); set_ul_sched_result(dci_result, &cc_result->ul_sched_result, ue_db);

@ -322,6 +322,22 @@ bool generate_rar_dci(sched_interface::dl_sched_rar_t& rar,
return true; return true;
} }
void generate_pdcch_order_dci(sched_interface::dl_sched_po_t& pdcch_order,
tti_point tti_tx_dl,
const sched_cell_params_t& cell_params,
uint32_t current_cfi)
{
// Generate DCI Format1A PDCCH order content
pdcch_order.dci.format = SRSRAN_DCI_FORMAT1A;
pdcch_order.dci.alloc_type = SRSRAN_RA_ALLOC_TYPE2; // TODO: is this correct?
pdcch_order.dci.rnti = pdcch_order.crnti;
pdcch_order.dci.is_pdcch_order = true;
pdcch_order.dci.preamble_idx = pdcch_order.preamble_idx;
pdcch_order.dci.prach_mask_idx = pdcch_order.prach_mask_idx;
get_mac_logger().debug("PDCCH order: rnti=0x%x", pdcch_order.dci.rnti);
}
void log_broadcast_allocation(const sched_interface::dl_sched_bc_t& bc, void log_broadcast_allocation(const sched_interface::dl_sched_bc_t& bc,
rbg_interval rbg_range, rbg_interval rbg_range,
const sched_cell_params_t& cell_params) const sched_cell_params_t& cell_params)
@ -384,4 +400,24 @@ void log_rar_allocation(const sched_interface::dl_sched_rar_t& rar, rbg_interval
srsran::to_c_str(str_buffer2)); srsran::to_c_str(str_buffer2));
} }
void log_po_allocation(const sched_interface::dl_sched_po_t& pdcch_order,
rbg_interval rbg_range,
const sched_cell_params_t& cell_params)
{
if (not get_mac_logger().info.enabled()) {
return;
}
fmt::memory_buffer str_buffer;
fmt::format_to(str_buffer, "{}", rbg_range);
get_mac_logger().info("SCHED: PDCCH order, cc=%d, rbgs=%s, dci=(%d,%d), tbs=%d, mcs=%d",
cell_params.enb_cc_idx,
srsran::to_c_str(str_buffer),
pdcch_order.dci.location.L,
pdcch_order.dci.location.ncce,
pdcch_order.tbs,
pdcch_order.dci.tb[0].mcs_idx);
}
} // namespace srsenb } // namespace srsenb

@ -52,6 +52,8 @@ sf_cch_allocator::get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user, uin
return &cc_cfg->common_locations[cfix]; return &cc_cfg->common_locations[cfix];
case alloc_type_t::DL_RAR: case alloc_type_t::DL_RAR:
return &cc_cfg->rar_locations[to_tx_dl(tti_rx).sf_idx()][cfix]; return &cc_cfg->rar_locations[to_tx_dl(tti_rx).sf_idx()][cfix];
case alloc_type_t::DL_PDCCH_ORDER:
return &cc_cfg->common_locations[cfix];
case alloc_type_t::DL_DATA: case alloc_type_t::DL_DATA:
case alloc_type_t::UL_DATA: case alloc_type_t::UL_DATA:
return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, to_tx_dl(tti_rx).sf_idx()); return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, to_tx_dl(tti_rx).sf_idx());

Loading…
Cancel
Save