remove rnti in mac/phy in staged manner. First the "upper mac", and then the "lower mac" and phy

master
Francisco Paisana 5 years ago
parent 493b7ea2da
commit 2cb80f9bf3

@ -103,7 +103,9 @@ public:
uint16_t allocate_rnti() final; uint16_t allocate_rnti() final;
private: private:
static const uint32_t cfi = 3; static const uint32_t cfi = 3;
bool check_ue_exists(uint16_t rnti);
std::mutex rnti_mutex; std::mutex rnti_mutex;
@ -133,7 +135,7 @@ private:
sched_interface::dl_pdu_mch_t mch = {}; sched_interface::dl_pdu_mch_t mch = {};
/* Map of active UEs */ /* Map of active UEs */
std::map<uint16_t, std::unique_ptr<ue> > ue_db; std::map<uint16_t, std::unique_ptr<ue> > ue_db, ues_to_rem;
uint16_t last_rnti = 70; uint16_t last_rnti = 70;
srslte::block_queue<std::unique_ptr<ue> > ue_pool; ///< Pool of pre-allocated UE objects srslte::block_queue<std::unique_ptr<ue> > ue_pool; ///< Pool of pre-allocated UE objects

@ -229,28 +229,27 @@ int mac::ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t* cfg)
// Removes UE from DB // Removes UE from DB
int mac::ue_rem(uint16_t rnti) int mac::ue_rem(uint16_t rnti)
{ {
int ret = -1; // Remove UE from the perspective of L2/L3
{ {
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_write_guard lock(rwlock);
if (ue_db.count(rnti)) { if (ue_db.count(rnti)) {
phy_h->rem_rnti(rnti); ues_to_rem[rnti] = std::move(ue_db[rnti]);
scheduler.ue_rem(rnti); ue_db.erase(rnti);
ret = 0;
} else { } else {
Error("User rnti=0x%x not found\n", rnti); Error("User rnti=0x%x not found\n", rnti);
return SRSLTE_ERROR;
} }
} }
if (ret) { scheduler.ue_rem(rnti);
return ret;
} // Remove UE from the perspective of L1
srslte::rwlock_write_guard lock(rwlock); // Note: Let any pending retx ACK to arrive, so that PHY recognizes rnti
if (ue_db.count(rnti)) { stack->defer_callback(FDD_HARQ_DELAY_DL_MS + FDD_HARQ_DELAY_UL_MS, [this, rnti]() {
ue_db.erase(rnti); phy_h->rem_rnti(rnti);
ues_to_rem.erase(rnti);
Info("User rnti=0x%x removed from MAC/PHY\n", rnti); Info("User rnti=0x%x removed from MAC/PHY\n", rnti);
} else { });
Error("User rnti=0x%x already removed\n", rnti); return SRSLTE_SUCCESS;
}
return 0;
} }
// Called after Msg3 // Called after Msg3
@ -295,17 +294,20 @@ void mac::get_metrics(mac_metrics_t metrics[ENB_METRICS_MAX_USERS])
int mac::ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) int mac::ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack)
{ {
srslte::rwlock_read_guard lock(rwlock);
log_h->step(tti); log_h->step(tti);
if (ue_db.count(rnti)) { srslte::rwlock_read_guard lock(rwlock);
uint32_t nof_bytes = scheduler.dl_ack_info(tti, rnti, enb_cc_idx, tb_idx, ack);
ue_db[rnti]->metrics_tx(ack, nof_bytes);
if (ack) { if (not check_ue_exists(rnti)) {
if (nof_bytes > 64) { // do not count RLC status messages only return SRSLTE_ERROR;
rrc_h->set_activity_user(rnti); }
log_h->info("DL activity rnti=0x%x, n_bytes=%d\n", rnti, nof_bytes);
} uint32_t nof_bytes = scheduler.dl_ack_info(tti, rnti, enb_cc_idx, tb_idx, ack);
ue_db[rnti]->metrics_tx(ack, nof_bytes);
if (ack) {
if (nof_bytes > 64) { // do not count RLC status messages only
rrc_h->set_activity_user(rnti);
log_h->info("DL activity rnti=0x%x, n_bytes=%d\n", rnti, nof_bytes);
} }
} }
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
@ -313,115 +315,105 @@ int mac::ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_
int mac::crc_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc) int mac::crc_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc)
{ {
int ret = SRSLTE_ERROR;
log_h->step(tti_rx); log_h->step(tti_rx);
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
if (ue_db.count(rnti)) { if (not check_ue_exists(rnti)) {
ue_db[rnti]->set_tti(tti_rx); return SRSLTE_ERROR;
ue_db[rnti]->metrics_rx(crc, nof_bytes); }
std::array<int, SRSLTE_MAX_CARRIERS> enb_ue_cc_map = scheduler.get_enb_ue_cc_map(rnti); ue_db[rnti]->set_tti(tti_rx);
if (enb_ue_cc_map[enb_cc_idx] < 0) { ue_db[rnti]->metrics_rx(crc, nof_bytes);
Error("User rnti=0x%x is not activated for carrier %d\n", rnti, enb_cc_idx);
return ret;
}
uint32_t ue_cc_idx = enb_ue_cc_map[enb_cc_idx];
// push the pdu through the queue if received correctly std::array<int, SRSLTE_MAX_CARRIERS> enb_ue_cc_map = scheduler.get_enb_ue_cc_map(rnti);
if (crc) { if (enb_ue_cc_map[enb_cc_idx] < 0) {
Info("Pushing PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes); Error("User rnti=0x%x is not activated for carrier %d\n", rnti, enb_cc_idx);
ue_db[rnti]->push_pdu(ue_cc_idx, tti_rx, nof_bytes); return SRSLTE_ERROR;
stack_task_queue.push([this]() { process_pdus(); }); }
} else { uint32_t ue_cc_idx = enb_ue_cc_map[enb_cc_idx];
ue_db[rnti]->deallocate_pdu(ue_cc_idx, tti_rx);
}
// Scheduler uses eNB's CC mapping // push the pdu through the queue if received correctly
ret = scheduler.ul_crc_info(tti_rx, rnti, enb_cc_idx, crc); if (crc) {
Info("Pushing PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes);
ue_db[rnti]->push_pdu(ue_cc_idx, tti_rx, nof_bytes);
stack_task_queue.push([this]() { process_pdus(); });
} else { } else {
Error("User rnti=0x%x not found\n", rnti); ue_db[rnti]->deallocate_pdu(ue_cc_idx, tti_rx);
} }
return ret; // Scheduler uses eNB's CC mapping
return scheduler.ul_crc_info(tti_rx, rnti, enb_cc_idx, crc);
} }
int mac::ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value) int mac::ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value)
{ {
int ret = SRSLTE_ERROR;
log_h->step(tti); log_h->step(tti);
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
if (ue_db.count(rnti)) { if (not check_ue_exists(rnti)) {
scheduler.dl_ri_info(tti, rnti, enb_cc_idx, ri_value); return SRSLTE_ERROR;
ue_db[rnti]->metrics_dl_ri(ri_value);
ret = SRSLTE_SUCCESS;
} else {
Error("User rnti=0x%x not found\n", rnti);
} }
return ret; scheduler.dl_ri_info(tti, rnti, enb_cc_idx, ri_value);
ue_db[rnti]->metrics_dl_ri(ri_value);
return SRSLTE_SUCCESS;
} }
int mac::pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi_value) int mac::pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi_value)
{ {
int ret = SRSLTE_ERROR;
log_h->step(tti); log_h->step(tti);
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
if (ue_db.count(rnti)) { if (not check_ue_exists(rnti)) {
scheduler.dl_pmi_info(tti, rnti, enb_cc_idx, pmi_value); return SRSLTE_ERROR;
ue_db[rnti]->metrics_dl_pmi(pmi_value);
ret = SRSLTE_SUCCESS;
} else {
Error("User rnti=0x%x not found\n", rnti);
} }
return ret; scheduler.dl_pmi_info(tti, rnti, enb_cc_idx, pmi_value);
ue_db[rnti]->metrics_dl_pmi(pmi_value);
return SRSLTE_SUCCESS;
} }
int mac::cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi_value) int mac::cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi_value)
{ {
int ret = SRSLTE_ERROR;
log_h->step(tti); log_h->step(tti);
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
if (ue_db.count(rnti)) { if (not check_ue_exists(rnti)) {
scheduler.dl_cqi_info(tti, rnti, enb_cc_idx, cqi_value); return SRSLTE_ERROR;
ue_db[rnti]->metrics_dl_cqi(cqi_value);
ret = SRSLTE_SUCCESS;
} else {
Error("User rnti=0x%x not found\n", rnti);
} }
return ret; scheduler.dl_cqi_info(tti, rnti, enb_cc_idx, cqi_value);
ue_db[rnti]->metrics_dl_cqi(cqi_value);
return SRSLTE_SUCCESS;
} }
int mac::snr_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, float snr) int mac::snr_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, float snr)
{ {
int ret = SRSLTE_ERROR;
log_h->step(tti); log_h->step(tti);
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
if (ue_db.count(rnti)) { if (not check_ue_exists(rnti)) {
uint32_t cqi = srslte_cqi_from_snr(snr); return SRSLTE_ERROR;
scheduler.ul_cqi_info(tti, rnti, enb_cc_idx, cqi, 0);
ret = SRSLTE_SUCCESS;
} else {
Error("User rnti=0x%x not found\n", rnti);
} }
return ret; uint32_t cqi = srslte_cqi_from_snr(snr);
return scheduler.ul_cqi_info(tti, rnti, enb_cc_idx, cqi, 0);
} }
int mac::ta_info(uint32_t tti, uint16_t rnti, float ta_us) int mac::ta_info(uint32_t tti, uint16_t rnti, float ta_us)
{ {
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
if (ue_db.count(rnti)) {
uint32_t nof_ta_count = ue_db[rnti]->set_ta_us(ta_us); if (not check_ue_exists(rnti)) {
if (nof_ta_count) { return SRSLTE_ERROR;
scheduler.dl_mac_buffer_state(rnti, (uint32_t)srslte::dl_sch_lcid::TA_CMD, nof_ta_count); }
}
uint32_t nof_ta_count = ue_db[rnti]->set_ta_us(ta_us);
if (nof_ta_count) {
scheduler.dl_mac_buffer_state(rnti, (uint32_t)srslte::dl_sch_lcid::TA_CMD, nof_ta_count);
} }
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
@ -429,15 +421,13 @@ int mac::ta_info(uint32_t tti, uint16_t rnti, float ta_us)
int mac::sr_detected(uint32_t tti, uint16_t rnti) int mac::sr_detected(uint32_t tti, uint16_t rnti)
{ {
log_h->step(tti); log_h->step(tti);
int ret = -1;
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
if (ue_db.count(rnti)) {
scheduler.ul_sr_info(tti, rnti); if (not check_ue_exists(rnti)) {
ret = 0; return SRSLTE_ERROR;
} else {
Error("User rnti=0x%x not found\n", rnti);
} }
return ret;
return scheduler.ul_sr_info(tti, rnti);
} }
uint16_t mac::allocate_rnti() uint16_t mac::allocate_rnti()
@ -901,4 +891,15 @@ void mac::write_mcch(sib_type2_s* sib2_, sib_type13_r9_s* sib13_, mcch_msg_s* mc
rrc_h->add_user(SRSLTE_MRNTI, {}); rrc_h->add_user(SRSLTE_MRNTI, {});
} }
bool mac::check_ue_exists(uint16_t rnti)
{
if (not ue_db.count(rnti)) {
if (not ues_to_rem.count(rnti)) {
Error("User rnti=0x%x not found\n", rnti);
}
return false;
}
return true;
}
} // namespace srsenb } // namespace srsenb

Loading…
Cancel
Save