use function helper for discard timer lookup and stopping in the PDCP

This commit is contained in:
Francisco 2021-02-20 14:11:59 +00:00 committed by Francisco Paisana
parent c6fa011eec
commit 047dd2a56d
2 changed files with 32 additions and 20 deletions

View File

@ -93,6 +93,8 @@ private:
// Discard callback (discardTimer) // Discard callback (discardTimer)
class discard_callback; class discard_callback;
std::vector<unique_timer> discard_timers; std::vector<unique_timer> discard_timers;
unique_timer* get_discard_timer(uint32_t sn);
void stop_discard_timer(uint32_t sn);
// TX Queue // TX Queue
uint32_t maximum_allocated_sns_window = 2048; uint32_t maximum_allocated_sns_window = 2048;

View File

@ -48,7 +48,8 @@ pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_,
uint32_t discard_time_value = static_cast<uint32_t>(cfg.discard_timer); uint32_t discard_time_value = static_cast<uint32_t>(cfg.discard_timer);
if (discard_time_value > 0) { if (discard_time_value > 0) {
discard_timers.reserve(maximum_pdcp_sn + 2); // the last SN is for status report // Note: One extra position is reserved at the end for the status report
discard_timers.reserve(maximum_pdcp_sn + 2);
for (uint32_t sn = 0; sn < maximum_pdcp_sn + 2; ++sn) { for (uint32_t sn = 0; sn < maximum_pdcp_sn + 2; ++sn) {
discard_timers.emplace_back(task_sched.get_unique_timer()); discard_timers.emplace_back(task_sched.get_unique_timer());
discard_callback discard_fnc(this, sn); discard_callback discard_fnc(this, sn);
@ -154,12 +155,14 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn)
} }
// Start discard timer // Start discard timer
if (cfg.discard_timer != pdcp_discard_timer_t::infinity and not discard_timers.empty()) { if (cfg.discard_timer != pdcp_discard_timer_t::infinity) {
uint32_t sn_idx = std::min(used_sn, (uint32_t)(discard_timers.size() - 1)); unique_timer* timer = get_discard_timer(used_sn);
discard_timers[sn_idx].run(); if (timer != nullptr) {
timer->run();
logger.debug("Discard Timer set for SN %u. Timeout: %ums", used_sn, static_cast<uint32_t>(cfg.discard_timer)); logger.debug("Discard Timer set for SN %u. Timeout: %ums", used_sn, static_cast<uint32_t>(cfg.discard_timer));
} }
} }
}
// check for pending security config in transmit direction // check for pending security config in transmit direction
if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast<int32_t>(tx_count)) { if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast<int32_t>(tx_count)) {
@ -538,10 +541,7 @@ void pdcp_entity_lte::handle_status_report_pdu(unique_byte_buffer_t pdu)
// Remove all SDUs with SN smaller than FMS // Remove all SDUs with SN smaller than FMS
for (auto it = undelivered_sdus_queue.begin(); it != undelivered_sdus_queue.end();) { for (auto it = undelivered_sdus_queue.begin(); it != undelivered_sdus_queue.end();) {
if (it->first < fms) { if (it->first < fms) {
if (not discard_timers.empty()) { stop_discard_timer(it->first);
uint32_t sn = std::min(it->first, (uint32_t)(discard_timers.size() - 1));
discard_timers[sn].stop();
}
it = undelivered_sdus_queue.erase(it); it = undelivered_sdus_queue.erase(it);
} else { } else {
++it; ++it;
@ -563,10 +563,7 @@ void pdcp_entity_lte::handle_status_report_pdu(unique_byte_buffer_t pdu)
for (uint32_t sn : acked_sns) { for (uint32_t sn : acked_sns) {
logger.debug("Status report ACKed SN=%d.", sn); logger.debug("Status report ACKed SN=%d.", sn);
undelivered_sdus_queue.erase(sn); undelivered_sdus_queue.erase(sn);
if (not discard_timers.empty()) { stop_discard_timer(sn);
uint32_t sn_idx = std::min(sn, (uint32_t)(discard_timers.size() - 1));
discard_timers[sn_idx].stop();
}
} }
} }
/**************************************************************************** /****************************************************************************
@ -641,9 +638,7 @@ void pdcp_entity_lte::discard_callback::operator()(uint32_t timer_id)
parent->rlc->discard_sdu(parent->lcid, discard_sn); parent->rlc->discard_sdu(parent->lcid, discard_sn);
// Remove timer from map // Remove timer from map
// NOTE: this will delete the callback. It *must* be the last instruction. parent->stop_discard_timer(discard_sn);
uint32_t sn_idx = std::min(discard_sn, (uint32_t)(parent->discard_timers.size() - 1));
parent->discard_timers[sn_idx].stop();
} }
/**************************************************************************** /****************************************************************************
@ -671,10 +666,7 @@ void pdcp_entity_lte::notify_delivery(const std::vector<uint32_t>& pdcp_sns)
// If ACK'ed bytes are equal to (or exceed) PDU size, remove PDU and disarm timer. // If ACK'ed bytes are equal to (or exceed) PDU size, remove PDU and disarm timer.
undelivered_sdus_queue.erase(sn); undelivered_sdus_queue.erase(sn);
if (not discard_timers.empty()) { stop_discard_timer(sn);
uint32_t sn_idx = std::min(sn, (uint32_t)(discard_timers.size() - 1));
discard_timers[sn].stop();
}
} }
} }
@ -737,6 +729,24 @@ uint32_t pdcp_entity_lte::nof_discard_timers() const
discard_timers.begin(), discard_timers.end(), [](const unique_timer& t) { return t.is_running(); }); discard_timers.begin(), discard_timers.end(), [](const unique_timer& t) { return t.is_running(); });
} }
unique_timer* pdcp_entity_lte::get_discard_timer(uint32_t sn)
{
// Note: When SN=-1 (Status report case), the position will be the last in the vector of discard timers
if (not discard_timers.empty()) {
uint32_t sn_idx = std::min((uint32_t)sn, (uint32_t)(discard_timers.size() - 1));
return &discard_timers[sn_idx];
}
return nullptr;
}
void pdcp_entity_lte::stop_discard_timer(uint32_t sn)
{
unique_timer* timer = get_discard_timer(sn);
if (timer != nullptr) {
timer->stop();
}
}
/**************************************************************************** /****************************************************************************
* Metrics helpers * Metrics helpers
***************************************************************************/ ***************************************************************************/