|
|
|
@ -14,8 +14,6 @@
|
|
|
|
|
#include "srsenb/hdr/stack/mac/sched_helpers.h"
|
|
|
|
|
#include "srslte/common/string_helpers.h"
|
|
|
|
|
|
|
|
|
|
using srslte::tti_point;
|
|
|
|
|
|
|
|
|
|
namespace srsenb {
|
|
|
|
|
|
|
|
|
|
const char* alloc_outcome_t::to_string() const
|
|
|
|
@ -401,9 +399,7 @@ sf_sched::ctrl_code_t sf_sched::alloc_dl_ctrl(uint32_t aggr_lvl, uint32_t tbs_by
|
|
|
|
|
// Allocation Successful
|
|
|
|
|
ctrl_alloc.dci_idx = tti_alloc.get_pdcch_grid().nof_allocs() - 1;
|
|
|
|
|
ctrl_alloc.rbg_range = ret.rbg_range;
|
|
|
|
|
ctrl_alloc.rnti = rnti;
|
|
|
|
|
ctrl_alloc.req_bytes = tbs_bytes;
|
|
|
|
|
ctrl_alloc.alloc_type = alloc_type;
|
|
|
|
|
|
|
|
|
|
return {ret.outcome, ctrl_alloc};
|
|
|
|
|
}
|
|
|
|
@ -424,8 +420,13 @@ alloc_outcome_t sf_sched::alloc_bc(uint32_t aggr_lvl, uint32_t sib_idx, uint32_t
|
|
|
|
|
|
|
|
|
|
// BC allocation successful
|
|
|
|
|
bc_alloc_t bc_alloc(ret.second);
|
|
|
|
|
bc_alloc.rv = rv;
|
|
|
|
|
bc_alloc.sib_idx = sib_idx;
|
|
|
|
|
|
|
|
|
|
if (not generate_sib_dci(
|
|
|
|
|
bc_alloc.bc_grant, get_tti_tx_dl(), sib_idx, sib_ntx, ret.second.rbg_range, *cc_cfg, tti_alloc.get_cfi())) {
|
|
|
|
|
logger.warning("SCHED: FAIL");
|
|
|
|
|
return alloc_outcome_t::ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bc_allocs.push_back(bc_alloc);
|
|
|
|
|
|
|
|
|
|
return ret.first;
|
|
|
|
@ -446,6 +447,13 @@ alloc_outcome_t sf_sched::alloc_paging(uint32_t aggr_lvl, uint32_t paging_payloa
|
|
|
|
|
|
|
|
|
|
// Paging allocation successful
|
|
|
|
|
bc_alloc_t bc_alloc(ret.second);
|
|
|
|
|
|
|
|
|
|
if (not generate_paging_dci(
|
|
|
|
|
bc_alloc.bc_grant, get_tti_tx_dl(), paging_payload, ret.second.rbg_range, *cc_cfg, tti_alloc.get_cfi())) {
|
|
|
|
|
logger.warning("SCHED: FAIL");
|
|
|
|
|
return alloc_outcome_t::ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bc_allocs.push_back(bc_alloc);
|
|
|
|
|
|
|
|
|
|
return ret.first;
|
|
|
|
@ -460,7 +468,7 @@ std::pair<alloc_outcome_t, uint32_t> sf_sched::alloc_rar(uint32_t aggr_lvl, cons
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (uint32_t nof_grants = rar.nof_grants; nof_grants > 0; nof_grants--) {
|
|
|
|
|
for (uint32_t nof_grants = rar.msg3_grant.size(); nof_grants > 0; nof_grants--) {
|
|
|
|
|
uint32_t buf_rar = 7 * nof_grants + 1; // 1+6 bytes per RAR subheader+body and 1 byte for Backoff
|
|
|
|
|
uint32_t total_msg3_size = msg3_grant_size * nof_grants;
|
|
|
|
|
|
|
|
|
@ -475,35 +483,30 @@ std::pair<alloc_outcome_t, uint32_t> sf_sched::alloc_rar(uint32_t aggr_lvl, cons
|
|
|
|
|
ret.first = ret2.first.result;
|
|
|
|
|
ret.second = nof_grants;
|
|
|
|
|
|
|
|
|
|
// if there was no space for the RAR, try again
|
|
|
|
|
if (ret.first == alloc_outcome_t::RB_COLLISION) {
|
|
|
|
|
continue;
|
|
|
|
|
if (ret.first == alloc_outcome_t::SUCCESS) {
|
|
|
|
|
sched_interface::dl_sched_rar_t rar_grant;
|
|
|
|
|
if (generate_rar_dci(rar_grant,
|
|
|
|
|
get_tti_tx_dl(),
|
|
|
|
|
rar,
|
|
|
|
|
ret2.second.rbg_range,
|
|
|
|
|
nof_grants,
|
|
|
|
|
last_msg3_prb,
|
|
|
|
|
*cc_cfg,
|
|
|
|
|
tti_alloc.get_cfi())) {
|
|
|
|
|
// RAR allocation successful
|
|
|
|
|
rar_allocs.emplace_back(ret2.second, rar_grant);
|
|
|
|
|
last_msg3_prb += msg3_grant_size * nof_grants;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
// if any other error, return
|
|
|
|
|
if (ret.first != alloc_outcome_t::SUCCESS) {
|
|
|
|
|
} else if (ret.first != alloc_outcome_t::RB_COLLISION) {
|
|
|
|
|
logger.warning("SCHED: Could not allocate RAR for L=%d, cause=%s", aggr_lvl, ret.first.to_string());
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RAR allocation successful
|
|
|
|
|
sched_interface::dl_sched_rar_t rar_grant = {};
|
|
|
|
|
rar_grant.msg3_grant.resize(nof_grants);
|
|
|
|
|
for (uint32_t i = 0; i < nof_grants; ++i) {
|
|
|
|
|
rar_grant.msg3_grant[i].data = rar.msg3_grant[i];
|
|
|
|
|
rar_grant.msg3_grant[i].grant.tpc_pusch = 3;
|
|
|
|
|
rar_grant.msg3_grant[i].grant.trunc_mcs = 0;
|
|
|
|
|
uint32_t rba = srslte_ra_type2_to_riv(msg3_grant_size, last_msg3_prb, cc_cfg->cfg.cell.nof_prb);
|
|
|
|
|
rar_grant.msg3_grant[i].grant.rba = rba;
|
|
|
|
|
|
|
|
|
|
last_msg3_prb += msg3_grant_size;
|
|
|
|
|
// if there was no space for the RAR, try again with a lower number of grants
|
|
|
|
|
}
|
|
|
|
|
rar_allocs.emplace_back(ret2.second, rar_grant);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (ret.first != alloc_outcome_t::SUCCESS) {
|
|
|
|
|
logger.info("SCHED: RAR allocation postponed due to lack of RBs");
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -652,7 +655,7 @@ alloc_outcome_t sf_sched::alloc_ul_user(sched_ue* user, prb_interval alloc)
|
|
|
|
|
bool has_retx = h->has_pending_retx();
|
|
|
|
|
if (not has_retx) {
|
|
|
|
|
alloc_type = ul_alloc_t::NEWTX;
|
|
|
|
|
} else if (h->retx_requires_pdcch(tti_point{get_tti_tx_ul()}, alloc)) {
|
|
|
|
|
} else if (h->retx_requires_pdcch(get_tti_tx_ul(), alloc)) {
|
|
|
|
|
alloc_type = ul_alloc_t::ADAPT_RETX;
|
|
|
|
|
} else {
|
|
|
|
|
alloc_type = ul_alloc_t::NOADAPT_RETX;
|
|
|
|
@ -694,68 +697,12 @@ void sf_sched::set_bc_sched_result(const sf_cch_allocator::alloc_result_t& dci_r
|
|
|
|
|
for (const auto& bc_alloc : bc_allocs) {
|
|
|
|
|
sched_interface::dl_sched_bc_t* bc = &dl_result->bc[dl_result->nof_bc_elems];
|
|
|
|
|
|
|
|
|
|
*bc = bc_alloc.bc_grant;
|
|
|
|
|
// assign NCCE/L
|
|
|
|
|
bc->dci.location = dci_result[bc_alloc.dci_idx]->dci_pos;
|
|
|
|
|
|
|
|
|
|
/* Generate DCI format1A */
|
|
|
|
|
prb_interval prb_range = prb_interval::rbgs_to_prbs(bc_alloc.rbg_range, cc_cfg->nof_prb());
|
|
|
|
|
int tbs = generate_format1a(prb_range, bc_alloc.req_bytes, bc_alloc.rv, bc_alloc.rnti, &bc->dci);
|
|
|
|
|
|
|
|
|
|
// Setup BC/Paging processes
|
|
|
|
|
if (bc_alloc.alloc_type == alloc_type_t::DL_BC) {
|
|
|
|
|
if (tbs <= (int)bc_alloc.req_bytes) {
|
|
|
|
|
logger.warning("SCHED: Error SIB%d, rbgs=(%d,%d), dci=(%d,%d), len=%d",
|
|
|
|
|
bc_alloc.sib_idx + 1,
|
|
|
|
|
bc_alloc.rbg_range.start(),
|
|
|
|
|
bc_alloc.rbg_range.stop(),
|
|
|
|
|
bc->dci.location.L,
|
|
|
|
|
bc->dci.location.ncce,
|
|
|
|
|
bc_alloc.req_bytes);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Setup BC process
|
|
|
|
|
bc->index = bc_alloc.sib_idx;
|
|
|
|
|
bc->type = sched_interface::dl_sched_bc_t::BCCH;
|
|
|
|
|
bc->tbs = (uint32_t)bc_alloc.req_bytes;
|
|
|
|
|
|
|
|
|
|
logger.debug("SCHED: SIB%d, rbgs=(%d,%d), dci=(%d,%d), rv=%d, len=%d, period=%d, mcs=%d",
|
|
|
|
|
bc_alloc.sib_idx + 1,
|
|
|
|
|
bc_alloc.rbg_range.start(),
|
|
|
|
|
bc_alloc.rbg_range.stop(),
|
|
|
|
|
bc->dci.location.L,
|
|
|
|
|
bc->dci.location.ncce,
|
|
|
|
|
bc_alloc.rv,
|
|
|
|
|
bc_alloc.req_bytes,
|
|
|
|
|
cc_cfg->cfg.sibs[bc_alloc.sib_idx].period_rf,
|
|
|
|
|
bc->dci.tb[0].mcs_idx);
|
|
|
|
|
} else {
|
|
|
|
|
// Paging
|
|
|
|
|
if (tbs <= 0) {
|
|
|
|
|
fmt::memory_buffer str_buffer;
|
|
|
|
|
fmt::format_to(str_buffer, "{}", bc_alloc.rbg_range);
|
|
|
|
|
logger.warning("SCHED: Error Paging, rbgs=%s, dci=(%d,%d)",
|
|
|
|
|
srslte::to_c_str(str_buffer),
|
|
|
|
|
bc->dci.location.L,
|
|
|
|
|
bc->dci.location.ncce);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Setup Paging process
|
|
|
|
|
bc->type = sched_interface::dl_sched_bc_t::PCCH;
|
|
|
|
|
bc->tbs = (uint32_t)tbs;
|
|
|
|
|
|
|
|
|
|
fmt::memory_buffer str_buffer;
|
|
|
|
|
fmt::format_to(str_buffer, "{}", bc_alloc.rbg_range);
|
|
|
|
|
logger.info("SCHED: PCH, rbgs=%s, dci=(%d,%d), tbs=%d, mcs=%d",
|
|
|
|
|
srslte::to_c_str(str_buffer),
|
|
|
|
|
bc->dci.location.L,
|
|
|
|
|
bc->dci.location.ncce,
|
|
|
|
|
tbs,
|
|
|
|
|
bc->dci.tb[0].mcs_idx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dl_result->nof_bc_elems++;
|
|
|
|
|
|
|
|
|
|
log_broadcast_allocation(*bc, bc_alloc.rbg_range, *cc_cfg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -765,45 +712,13 @@ void sf_sched::set_rar_sched_result(const sf_cch_allocator::alloc_result_t& dci_
|
|
|
|
|
for (const auto& rar_alloc : rar_allocs) {
|
|
|
|
|
sched_interface::dl_sched_rar_t* rar = &dl_result->rar[dl_result->nof_rar_elems];
|
|
|
|
|
|
|
|
|
|
// Setup RAR process
|
|
|
|
|
*rar = rar_alloc.rar_grant;
|
|
|
|
|
// Assign NCCE/L
|
|
|
|
|
rar->dci.location = dci_result[rar_alloc.alloc_data.dci_idx]->dci_pos;
|
|
|
|
|
|
|
|
|
|
/* Generate DCI format1A */
|
|
|
|
|
prb_interval prb_range = prb_interval::rbgs_to_prbs(rar_alloc.alloc_data.rbg_range, cc_cfg->nof_prb());
|
|
|
|
|
int tbs = generate_format1a(prb_range, rar_alloc.alloc_data.req_bytes, 0, rar_alloc.alloc_data.rnti, &rar->dci);
|
|
|
|
|
if (tbs <= 0) {
|
|
|
|
|
fmt::memory_buffer str_buffer;
|
|
|
|
|
fmt::format_to(str_buffer, "{}", rar_alloc.alloc_data.rbg_range);
|
|
|
|
|
logger.warning("SCHED: Error RAR, ra_rnti_idx=%d, rbgs=%s, dci=(%d,%d)",
|
|
|
|
|
rar_alloc.alloc_data.rnti,
|
|
|
|
|
srslte::to_c_str(str_buffer),
|
|
|
|
|
rar->dci.location.L,
|
|
|
|
|
rar->dci.location.ncce);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Setup RAR process
|
|
|
|
|
rar->tbs = rar_alloc.alloc_data.req_bytes;
|
|
|
|
|
rar->msg3_grant = rar_alloc.rar_grant.msg3_grant;
|
|
|
|
|
|
|
|
|
|
// Print RAR allocation result
|
|
|
|
|
for (uint32_t i = 0; i < rar->msg3_grant.size(); ++i) {
|
|
|
|
|
const auto& msg3_grant = rar->msg3_grant[i];
|
|
|
|
|
uint16_t expected_rnti = msg3_grant.data.temp_crnti;
|
|
|
|
|
fmt::memory_buffer str_buffer;
|
|
|
|
|
fmt::format_to(str_buffer, "{}", rar_alloc.alloc_data.rbg_range);
|
|
|
|
|
logger.info("SCHED: RAR, temp_crnti=0x%x, ra-rnti=%d, rbgs=%s, dci=(%d,%d), rar_grant_rba=%d, "
|
|
|
|
|
"rar_grant_mcs=%d",
|
|
|
|
|
expected_rnti,
|
|
|
|
|
rar_alloc.alloc_data.rnti,
|
|
|
|
|
srslte::to_c_str(str_buffer),
|
|
|
|
|
rar->dci.location.L,
|
|
|
|
|
rar->dci.location.ncce,
|
|
|
|
|
msg3_grant.grant.rba,
|
|
|
|
|
msg3_grant.grant.trunc_mcs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dl_result->nof_rar_elems++;
|
|
|
|
|
|
|
|
|
|
log_rar_allocation(*rar, rar_alloc.alloc_data.rbg_range);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1093,53 +1008,4 @@ uint32_t sf_sched::get_nof_ctrl_symbols() const
|
|
|
|
|
return tti_alloc.get_cfi() + ((cc_cfg->cfg.cell.nof_prb <= 10) ? 1 : 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sf_sched::generate_format1a(prb_interval prb_range,
|
|
|
|
|
uint32_t tbs_bytes,
|
|
|
|
|
uint32_t rv,
|
|
|
|
|
uint16_t rnti,
|
|
|
|
|
srslte_dci_dl_t* dci)
|
|
|
|
|
{
|
|
|
|
|
/* Calculate I_tbs for this TBS */
|
|
|
|
|
int tbs = tbs_bytes * 8;
|
|
|
|
|
int i;
|
|
|
|
|
int mcs = -1;
|
|
|
|
|
for (i = 0; i < 27; i++) {
|
|
|
|
|
if (srslte_ra_tbs_from_idx(i, 2) >= tbs) {
|
|
|
|
|
dci->type2_alloc.n_prb1a = srslte_ra_type2_t::SRSLTE_RA_TYPE2_NPRB1A_2;
|
|
|
|
|
mcs = i;
|
|
|
|
|
tbs = srslte_ra_tbs_from_idx(i, 2);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (srslte_ra_tbs_from_idx(i, 3) >= tbs) {
|
|
|
|
|
dci->type2_alloc.n_prb1a = srslte_ra_type2_t::SRSLTE_RA_TYPE2_NPRB1A_3;
|
|
|
|
|
mcs = i;
|
|
|
|
|
tbs = srslte_ra_tbs_from_idx(i, 3);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (i == 28) {
|
|
|
|
|
logger.error("Can't allocate Format 1A for TBS=%d", tbs);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger.debug("ra_tbs=%d/%d, tbs_bytes=%d, tbs=%d, mcs=%d",
|
|
|
|
|
srslte_ra_tbs_from_idx(mcs, 2),
|
|
|
|
|
srslte_ra_tbs_from_idx(mcs, 3),
|
|
|
|
|
tbs_bytes,
|
|
|
|
|
tbs,
|
|
|
|
|
mcs);
|
|
|
|
|
|
|
|
|
|
dci->alloc_type = SRSLTE_RA_ALLOC_TYPE2;
|
|
|
|
|
dci->type2_alloc.mode = srslte_ra_type2_t::SRSLTE_RA_TYPE2_LOC;
|
|
|
|
|
dci->type2_alloc.riv = srslte_ra_type2_to_riv(prb_range.length(), prb_range.start(), cc_cfg->cfg.cell.nof_prb);
|
|
|
|
|
dci->pid = 0;
|
|
|
|
|
dci->tb[0].mcs_idx = mcs;
|
|
|
|
|
dci->tb[0].rv = rv;
|
|
|
|
|
dci->format = SRSLTE_DCI_FORMAT1A;
|
|
|
|
|
dci->rnti = rnti;
|
|
|
|
|
dci->ue_cc_idx = std::numeric_limits<uint32_t>::max();
|
|
|
|
|
|
|
|
|
|
return tbs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace srsenb
|
|
|
|
|