/** * * \section COPYRIGHT * * Copyright 2013-2020 Software Radio Systems Limited * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the distribution. * */ #ifndef SRSLTE_SCHED_HELPERS_H #define SRSLTE_SCHED_HELPERS_H #include "srsenb/hdr/stack/mac/sched_common.h" #include "srslte/common/logmap.h" #include "srslte/interfaces/sched_interface.h" namespace srsenb { inline uint32_t aggr_level(uint32_t aggr_idx) { return 1u << aggr_idx; } /// Obtain rvidx from nof retxs. This value is stored in DCI inline uint32_t get_rvidx(uint32_t retx_idx) { const static uint32_t rv_idx[4] = {0, 2, 3, 1}; return rv_idx[retx_idx % 4]; } /// Obtain nof retxs from rvidx. inline uint32_t get_nof_retx(uint32_t rv_idx) { const static uint32_t nof_retxs[4] = {0, 3, 1, 2}; return nof_retxs[rv_idx % 4]; } /// convert cell nof PRBs to nof RBGs inline uint32_t cell_nof_prb_to_rbg(uint32_t nof_prbs) { switch (nof_prbs) { case 6: return 6; case 15: return 8; case 25: return 13; case 50: return 17; case 75: return 19; case 100: return 25; default: srslte::logmap::get("MAC")->error("Provided nof PRBs not valid"); return 0; } } /// convert cell nof RBGs to nof PRBs inline uint32_t cell_nof_rbg_to_prb(uint32_t nof_rbgs) { switch (nof_rbgs) { case 6: return 6; case 8: return 15; case 13: return 25; case 17: return 50; case 19: return 75; case 25: return 100; default: srslte::logmap::get("MAC")->error("Provided nof PRBs not valid"); return 0; } } /** * Count number of PRBs present in a DL RBG mask * @param cell_nof_prb cell nof prbs * @param P cell ratio prb/rbg * @param bitmask DL RBG mask * @return number of prbs */ inline uint32_t count_prb_per_tb(const rbgmask_t& bitmask) { uint32_t Nprb = cell_nof_rbg_to_prb(bitmask.size()); uint32_t P = srslte_ra_type0_P(Nprb); uint32_t nof_prb = P * bitmask.count(); if (bitmask.test(bitmask.size() - 1)) { nof_prb -= bitmask.size() * P - Nprb; } return nof_prb; } inline uint32_t count_prb_per_tb_approx(uint32_t nof_rbgs, uint32_t cell_nof_prb) { uint32_t P = srslte_ra_type0_P(cell_nof_prb); return std::min(nof_rbgs * P, cell_nof_prb); } ue_cce_locations_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg); /** * Generate possible CCE locations a user can use to allocate DCIs * @param regs Regs data for the given cell configuration * @param location Result of the CCE location computation. * @param cfi Number of control symbols used for the PDCCH * @param sf_idx subframe index specific to the tx TTI (relevant only for data and RAR transmissions) * @param rnti identity of the user (invalid RNTI for RAR and BC transmissions) */ void generate_cce_location(srslte_regs_t* regs, sched_dci_cce_t* location, uint32_t cfi, uint32_t sf_idx = 0, uint16_t rnti = SRSLTE_INVALID_RNTI); /// Obtains TB size *in bytes* for a given MCS and nof allocated prbs inline uint32_t get_tbs_bytes(uint32_t mcs, uint32_t nof_alloc_prb, bool use_tbs_index_alt, bool is_ul) { int tbs_idx = srslte_ra_tbs_idx_from_mcs(mcs, use_tbs_index_alt, is_ul); assert(tbs_idx != SRSLTE_ERROR); int tbs = srslte_ra_tbs_from_idx((uint32_t)tbs_idx, nof_alloc_prb); assert(tbs != SRSLTE_ERROR); return (uint32_t)tbs / 8U; } /// Find lowest DCI aggregation level supported by the UE spectral efficiency uint32_t get_aggr_level(uint32_t nof_bits, uint32_t dl_cqi, uint32_t max_aggr_lvl, uint32_t cell_nof_prb, bool use_tbs_index_alt); /******************************************************* * sched_interface helper functions *******************************************************/ inline bool operator==(const sched_interface::ue_cfg_t::cc_cfg_t& lhs, const sched_interface::ue_cfg_t::cc_cfg_t& rhs) { return lhs.enb_cc_idx == rhs.enb_cc_idx and lhs.active == rhs.active; } /// sanity check the UE CC configuration int check_ue_cfg_correctness(const sched_interface::ue_cfg_t& ue_cfg); /// Logs DL MAC PDU contents void log_dl_cc_results(srslte::log_ref log_h, uint32_t enb_cc_idx, const sched_interface::dl_sched_res_t& result); /// Logs PHICH contents void log_phich_cc_results(srslte::log_ref log_h, uint32_t enb_cc_idx, const sched_interface::ul_sched_res_t& result); const char* to_string(sched_interface::ue_bearer_cfg_t::direction_t dir); } // namespace srsenb #endif // SRSLTE_SCHED_HELPERS_H