mirror of https://github.com/PentHertz/srsLTE.git
use mini state machine for ConRes CE scheduling instead of relying that there is data in the DL buffer
This commit is contained in:
parent
6de7b644ec
commit
d716d8bf7e
|
@ -161,6 +161,11 @@ public:
|
|||
//! Get UL Harq for a given tti_tx_ul
|
||||
ul_harq_proc* get_ul_harq(uint32_t tti_tx_ul);
|
||||
|
||||
/**
|
||||
* Set ACK state for UL Harq Proc
|
||||
*/
|
||||
std::pair<bool, uint32_t> set_ul_crc(srslte::tti_point tti_tx_ul, uint32_t tb_idx, bool ack_);
|
||||
|
||||
//! Resets pending harq ACKs and cleans UL Harqs with maxretx == 0
|
||||
void reset_pending_data(uint32_t tti_rx);
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ public:
|
|||
std::pair<bool, uint32_t> get_cell_index(uint32_t enb_cc_idx) const;
|
||||
const sched_interface::ue_cfg_t& get_ue_cfg() const { return cfg; }
|
||||
uint32_t get_aggr_level(uint32_t ue_cc_idx, uint32_t nof_bits);
|
||||
void sched_conres_ce(uint32_t msg3_tti_tx_ul);
|
||||
|
||||
/*******************************************************
|
||||
* Functions used by scheduler metric objects
|
||||
|
@ -142,7 +143,7 @@ public:
|
|||
|
||||
dl_harq_proc* get_pending_dl_harq(uint32_t tti_tx_dl, uint32_t cc_idx);
|
||||
dl_harq_proc* get_empty_dl_harq(uint32_t tti_tx_dl, uint32_t cc_idx);
|
||||
ul_harq_proc* get_ul_harq(uint32_t tti, uint32_t cc_idx);
|
||||
ul_harq_proc* get_ul_harq(uint32_t tti, uint32_t ue_cc_idx);
|
||||
|
||||
/*******************************************************
|
||||
* Functions used by the scheduler carrier object
|
||||
|
@ -261,7 +262,13 @@ private:
|
|||
uint32_t max_msg3retx = 0;
|
||||
|
||||
/* User State */
|
||||
bool conres_ce_pending = true;
|
||||
enum class ra_state_t {
|
||||
msg3_sched_pending,
|
||||
wait_msg3_ack,
|
||||
conres_sched_pending,
|
||||
conres_sent
|
||||
} conres_state = ra_state_t::msg3_sched_pending;
|
||||
uint32_t msg3_pid = 0;
|
||||
|
||||
int next_tpc_pusch = 0;
|
||||
int next_tpc_pucch = 0;
|
||||
|
|
|
@ -240,10 +240,11 @@ void ra_sched::ul_sched(sf_sched* sf_dl_sched, sf_sched* sf_msg3_sched)
|
|||
|
||||
uint16_t crnti = msg3grant.data.temp_crnti;
|
||||
auto user_it = ue_db->find(crnti);
|
||||
if (user_it == ue_db->end() or not sf_msg3_sched->alloc_msg3(&user_it->second, msg3grant)) {
|
||||
log_h->error("SCHED: Failed to allocate Msg3 for rnti=0x%x at tti=%d\n", crnti, sf_msg3_sched->get_tti_tx_ul());
|
||||
} else {
|
||||
if (user_it != ue_db->end() and sf_msg3_sched->alloc_msg3(&user_it->second, msg3grant)) {
|
||||
log_h->debug("SCHED: Queueing Msg3 for rnti=0x%x at tti=%d\n", crnti, sf_msg3_sched->get_tti_tx_ul());
|
||||
user_it->second.sched_conres_ce(sf_msg3_sched->get_tti_tx_ul());
|
||||
} else {
|
||||
log_h->error("SCHED: Failed to allocate Msg3 for rnti=0x%x at tti=%d\n", crnti, sf_msg3_sched->get_tti_tx_ul());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -366,10 +366,17 @@ ul_harq_proc* harq_entity::get_ul_harq(uint32_t tti_tx_ul)
|
|||
return &ul_harqs[tti_tx_ul % ul_harqs.size()];
|
||||
}
|
||||
|
||||
std::pair<bool, uint32_t> harq_entity::set_ul_crc(srslte::tti_point tti_rx, uint32_t tb_idx, bool ack_)
|
||||
{
|
||||
ul_harq_proc* h = get_ul_harq(tti_rx.to_uint());
|
||||
uint32_t pid = h->get_id();
|
||||
return {h->set_ack(tb_idx, ack_), pid};
|
||||
}
|
||||
|
||||
void harq_entity::reset_pending_data(uint32_t tti_rx)
|
||||
{
|
||||
tti_point tti_tx_ul = tti_point{tti_rx} + FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS;
|
||||
tti_point tti_tx_dl = tti_point{tti_rx} + FDD_HARQ_DELAY_UL_MS;
|
||||
tti_point tti_tx_ul = srslte::to_tx_ul(tti_point{tti_rx});
|
||||
tti_point tti_tx_dl = srslte::to_tx_dl(tti_point{tti_rx});
|
||||
|
||||
// Reset ACK state of UL Harq
|
||||
get_ul_harq(tti_tx_ul.to_uint())->reset_pending_data();
|
||||
|
|
|
@ -144,8 +144,7 @@ void sched_ue::set_cfg(const sched_interface::ue_cfg_t& cfg_)
|
|||
carriers[ue_idx] = sched_ue_carrier{cfg, (*cell_params_list)[cc_cfg.enb_cc_idx], rnti, ue_idx};
|
||||
if (ue_idx == 0) {
|
||||
// PCell was changed possibly due to handover. Schedule a new ConRes CE to be transmitted after the Msg3
|
||||
conres_ce_pending = true;
|
||||
lch[0].buf_tx = std::max(lch[0].buf_tx, 1); // TODO: find a cleaner way to schedule conres CE
|
||||
conres_state = ra_state_t::conres_sched_pending;
|
||||
log_h->info("SCHED: PCell has changed. ConRes CE scheduled\n");
|
||||
}
|
||||
} else {
|
||||
|
@ -171,7 +170,7 @@ void sched_ue::reset()
|
|||
buf_ul = 0;
|
||||
phy_config_dedicated_enabled = false;
|
||||
cqi_request_tti = 0;
|
||||
conres_ce_pending = true;
|
||||
conres_state = ra_state_t::msg3_sched_pending;
|
||||
carriers.clear();
|
||||
|
||||
// erase all bearers
|
||||
|
@ -306,9 +305,13 @@ void sched_ue::set_ul_crc(srslte::tti_point tti_rx, uint32_t enb_cc_idx, bool cr
|
|||
{
|
||||
auto p = get_cell_index(enb_cc_idx);
|
||||
if (p.first) {
|
||||
srslte::tti_point tti_tx_ul = srslte::to_tx_ul(tti_rx);
|
||||
if (not get_ul_harq(tti_tx_ul.to_uint(), p.second)->set_ack(0, crc_res)) {
|
||||
log_h->warning("Received UL CRC for invalid tti_tx_ul=%d\n", (int)tti_tx_ul.to_uint());
|
||||
auto ret = carriers[p.second].harq_ent.set_ul_crc(tti_rx, 0, crc_res);
|
||||
if (not ret.first) {
|
||||
log_h->warning("Received UL CRC for invalid tti_rx=%d\n", (int)tti_rx.to_uint());
|
||||
} else {
|
||||
if (conres_state == ra_state_t::wait_msg3_ack and ret.second == msg3_pid and crc_res) {
|
||||
conres_state = ra_state_t::conres_sched_pending;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_h->warning("Received UL CRC for invalid cell index %d\n", enb_cc_idx);
|
||||
|
@ -468,7 +471,7 @@ int sched_ue::generate_format1(uint32_t pid,
|
|||
if (is_conres_ce_pending()) {
|
||||
data->pdu[0][data->nof_pdu_elems[0]].lcid = srslte::sch_subh::CON_RES_ID;
|
||||
data->nof_pdu_elems[0]++;
|
||||
conres_ce_pending = false;
|
||||
conres_state = ra_state_t::conres_sent;
|
||||
Info("SCHED: Added MAC Contention Resolution CE for rnti=0x%x\n", rnti);
|
||||
}
|
||||
|
||||
|
@ -810,7 +813,7 @@ bool sched_ue::needs_cqi_unlocked(uint32_t tti, uint32_t cc_idx, bool will_be_se
|
|||
|
||||
bool sched_ue::is_conres_ce_pending() const
|
||||
{
|
||||
return conres_ce_pending and bearer_is_dl(&lch[0]) and (lch[0].buf_retx > 0 or lch[0].buf_tx > 0);
|
||||
return conres_state == ra_state_t::conres_sched_pending;
|
||||
}
|
||||
|
||||
/// Use this function in the dl-metric to get the bytes to be scheduled. It accounts for the UE data,
|
||||
|
@ -892,13 +895,17 @@ std::pair<uint32_t, uint32_t> sched_ue::get_requested_dl_bytes(uint32_t ue_cc_id
|
|||
log_h->error("SRB0 must always be activated for DL\n");
|
||||
return {0, 0};
|
||||
}
|
||||
if (conres_state == ra_state_t::msg3_sched_pending or conres_state == ra_state_t::wait_msg3_ack) {
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
uint32_t max_data = 0, min_data = 0;
|
||||
uint32_t srb0_data = 0, rb_data = 0, sum_ce_data = 0;
|
||||
bool is_dci_format1 = get_dci_format() == SRSLTE_DCI_FORMAT1;
|
||||
if (is_dci_format1 and (lch[0].buf_tx > 0 or lch[0].buf_retx > 0)) {
|
||||
srb0_data = compute_sdu_total_bytes(0, lch[0].buf_retx);
|
||||
srb0_data += compute_sdu_total_bytes(0, lch[0].buf_tx);
|
||||
if (conres_ce_pending) {
|
||||
if (is_conres_ce_pending()) {
|
||||
sum_ce_data = sched_utils::conres_ce_size + ce_subheader_size;
|
||||
}
|
||||
}
|
||||
|
@ -920,7 +927,7 @@ std::pair<uint32_t, uint32_t> sched_ue::get_requested_dl_bytes(uint32_t ue_cc_id
|
|||
/* Set Minimum boundary */
|
||||
if (srb0_data > 0) {
|
||||
min_data = srb0_data;
|
||||
if (conres_ce_pending) {
|
||||
if (is_conres_ce_pending()) {
|
||||
min_data += sched_utils::conres_ce_size + ce_subheader_size;
|
||||
}
|
||||
} else {
|
||||
|
@ -940,6 +947,9 @@ std::pair<uint32_t, uint32_t> sched_ue::get_requested_dl_bytes(uint32_t ue_cc_id
|
|||
*/
|
||||
uint32_t sched_ue::get_pending_dl_new_data()
|
||||
{
|
||||
if (conres_state == ra_state_t::msg3_sched_pending or conres_state == ra_state_t::wait_msg3_ack) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t pending_data = 0;
|
||||
for (int i = 0; i < sched_interface::MAX_LC; i++) {
|
||||
if (bearer_is_dl(&lch[i])) {
|
||||
|
@ -1085,6 +1095,12 @@ uint32_t sched_ue::get_aggr_level(uint32_t ue_cc_idx, uint32_t nof_bits)
|
|||
return carriers[ue_cc_idx].get_aggr_level(nof_bits);
|
||||
}
|
||||
|
||||
void sched_ue::sched_conres_ce(uint32_t msg3_tti_tx_ul)
|
||||
{
|
||||
msg3_pid = carriers[0].harq_ent.get_ul_harq(msg3_tti_tx_ul)->get_id();
|
||||
conres_state = ra_state_t::wait_msg3_ack;
|
||||
}
|
||||
|
||||
void sched_ue::finish_tti(const tti_params_t& tti_params, uint32_t enb_cc_idx)
|
||||
{
|
||||
auto p = get_cell_index(enb_cc_idx);
|
||||
|
|
|
@ -37,8 +37,10 @@ public:
|
|||
int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) override { return 0; }
|
||||
void phy_config_enabled(uint16_t rnti, bool enabled) override {}
|
||||
void write_mcch(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13, asn1::rrc::mcch_msg_s* mcch) override
|
||||
{
|
||||
}
|
||||
{}
|
||||
uint16_t allocate_rnti() override { return last_rnti++; }
|
||||
|
||||
uint16_t last_rnti = 70;
|
||||
};
|
||||
|
||||
class rlc_dummy : public rlc_interface_rrc
|
||||
|
|
|
@ -196,15 +196,16 @@ int test_scell_activation(test_scell_activation_params params)
|
|||
|
||||
// Event: Wait for UE to receive and ack CE. Send cqi==0, which should not activate the SCell
|
||||
uint32_t cqi = 0;
|
||||
for (uint32_t cidx = 1; cidx < cc_idxs.size(); ++cidx) {
|
||||
for (uint32_t i = 0; i < FDD_HARQ_DELAY_UL_MS; ++i) {
|
||||
tester.dl_cqi_info(tester.tti_info.tti_params.tti_rx, rnti1, 1, cqi);
|
||||
tester.dl_cqi_info(tester.tti_info.tti_params.tti_rx, rnti1, cc_idxs[cidx], cqi);
|
||||
generator.step_tti();
|
||||
}
|
||||
}
|
||||
tester.test_next_ttis(generator.tti_events);
|
||||
// The UE should now have received the CE
|
||||
|
||||
// Event: Generate a bit more data, it should *not* go through SCells until we send a CQI
|
||||
tester.dl_cqi_info(tester.tti_info.tti_params.tti_rx, rnti1, 1, cqi);
|
||||
generate_data(5, P_dl, P_ul_sr, randf());
|
||||
tester.test_next_ttis(generator.tti_events);
|
||||
TESTASSERT(tester.sched_stats->users[rnti1].tot_dl_sched_data[params.pcell_idx] > 0);
|
||||
|
|
|
@ -831,7 +831,7 @@ int common_sched_tester::schedule_acks()
|
|||
if (ack_data.ul_harq.nof_retx(0) == 0) {
|
||||
ack_data.ack = randf() > sim_args0.P_retx;
|
||||
} else {
|
||||
ack_data.ack = ack_data.ul_harq.nof_retx(0) == 3;
|
||||
ack_data.ack = ack_data.ul_harq.nof_retx(0) == 2;
|
||||
}
|
||||
to_ul_ack.insert(std::make_pair(ack_data.tti_tx_ul, ack_data));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue