|
|
@ -38,6 +38,7 @@ pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_,
|
|
|
|
reordering_window = 2048;
|
|
|
|
reordering_window = 2048;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Initial state
|
|
|
|
st.next_pdcp_tx_sn = 0;
|
|
|
|
st.next_pdcp_tx_sn = 0;
|
|
|
|
st.tx_hfn = 0;
|
|
|
|
st.tx_hfn = 0;
|
|
|
|
st.rx_hfn = 0;
|
|
|
|
st.rx_hfn = 0;
|
|
|
@ -45,6 +46,9 @@ pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_,
|
|
|
|
maximum_pdcp_sn = (1 << cfg.sn_len) - 1;
|
|
|
|
maximum_pdcp_sn = (1 << cfg.sn_len) - 1;
|
|
|
|
st.last_submitted_pdcp_rx_sn = maximum_pdcp_sn;
|
|
|
|
st.last_submitted_pdcp_rx_sn = maximum_pdcp_sn;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Queue Helpers
|
|
|
|
|
|
|
|
maximum_allocated_sns_window = (1 << cfg.sn_len) / 2;
|
|
|
|
|
|
|
|
|
|
|
|
logger.info("Init %s with bearer ID: %d", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id);
|
|
|
|
logger.info("Init %s with bearer ID: %d", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id);
|
|
|
|
logger.info("SN len bits: %d, SN len bytes: %d, reordering window: %d, Maximum SN: %d, discard timer: %d ms",
|
|
|
|
logger.info("SN len bits: %d, SN len bytes: %d, reordering window: %d, Maximum SN: %d, discard timer: %d ms",
|
|
|
|
cfg.sn_len,
|
|
|
|
cfg.sn_len,
|
|
|
@ -134,7 +138,10 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn)
|
|
|
|
// a succesfull transmission or when the discard timer expires.
|
|
|
|
// a succesfull transmission or when the discard timer expires.
|
|
|
|
// Status report will also use this queue, to know the First Missing SDU (FMS).
|
|
|
|
// Status report will also use this queue, to know the First Missing SDU (FMS).
|
|
|
|
if (!rlc->rb_is_um(lcid)) {
|
|
|
|
if (!rlc->rb_is_um(lcid)) {
|
|
|
|
store_sdu(used_sn, sdu);
|
|
|
|
if (not store_sdu(used_sn, sdu)) {
|
|
|
|
|
|
|
|
// Could not store the SDU, discarding
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// check for pending security config in transmit direction
|
|
|
|
// check for pending security config in transmit direction
|
|
|
@ -547,17 +554,33 @@ void pdcp_entity_lte::handle_status_report_pdu(unique_byte_buffer_t pdu)
|
|
|
|
/****************************************************************************
|
|
|
|
/****************************************************************************
|
|
|
|
* TX PDUs Queue Helper
|
|
|
|
* TX PDUs Queue Helper
|
|
|
|
***************************************************************************/
|
|
|
|
***************************************************************************/
|
|
|
|
bool pdcp_entity_lte::store_sdu(uint32_t tx_count, const unique_byte_buffer_t& sdu)
|
|
|
|
bool pdcp_entity_lte::store_sdu(uint32_t sn, const unique_byte_buffer_t& sdu)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
logger.debug(
|
|
|
|
logger.debug("Storing SDU in undelivered SDUs queue. SN=%d, Queue size=%ld", sn, undelivered_sdus_queue.size());
|
|
|
|
"Storing SDU in undelivered SDUs queue. TX_COUNT=%d, Queue size=%ld", tx_count, undelivered_sdus_queue.size());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check wether PDU is already in the queue
|
|
|
|
// Check wether PDU is already in the queue
|
|
|
|
if (undelivered_sdus_queue.find(tx_count) != undelivered_sdus_queue.end()) {
|
|
|
|
if (undelivered_sdus_queue.find(sn) != undelivered_sdus_queue.end()) {
|
|
|
|
logger.error("PDU already exists in the queue. TX_COUNT=%d", tx_count);
|
|
|
|
logger.error("PDU already exists in the queue. TX_COUNT=%d", sn);
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure we don't associate more than half of the PDCP SN space of contiguous PDCP SDUs
|
|
|
|
|
|
|
|
if (not undelivered_sdus_queue.empty()) {
|
|
|
|
|
|
|
|
auto fms_it = undelivered_sdus_queue.begin();
|
|
|
|
|
|
|
|
uint32_t fms_sn = fms_it->first;
|
|
|
|
|
|
|
|
int32_t diff = sn - fms_sn;
|
|
|
|
|
|
|
|
if (diff > 0 && (uint32_t)diff > maximum_allocated_sns_window) {
|
|
|
|
|
|
|
|
// This SN is too large to assign, it may cause HFN de-synchronization.
|
|
|
|
|
|
|
|
logger.debug("This SN is too large to assign. Discarding. SN=%d, FMS=%d, diff=%d", sn, fms_sn, diff);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (diff < 0 && diff < ((-1) * (int32_t)maximum_allocated_sns_window)) {
|
|
|
|
|
|
|
|
// This SN is too large to assign, it may cause HFN de-synchronization.
|
|
|
|
|
|
|
|
logger.debug("This SN is too large to assign. Discarding. SN=%d, FMS=%d, diff=%d", sn, fms_sn, diff);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Copy PDU contents into queue
|
|
|
|
// Copy PDU contents into queue
|
|
|
|
unique_byte_buffer_t sdu_copy = make_byte_buffer();
|
|
|
|
unique_byte_buffer_t sdu_copy = make_byte_buffer();
|
|
|
|
memcpy(sdu_copy->msg, sdu->msg, sdu->N_bytes);
|
|
|
|
memcpy(sdu_copy->msg, sdu->msg, sdu->N_bytes);
|
|
|
@ -566,7 +589,7 @@ bool pdcp_entity_lte::store_sdu(uint32_t tx_count, const unique_byte_buffer_t& s
|
|
|
|
// Metrics
|
|
|
|
// Metrics
|
|
|
|
sdu_copy->set_timestamp();
|
|
|
|
sdu_copy->set_timestamp();
|
|
|
|
|
|
|
|
|
|
|
|
undelivered_sdus_queue.insert(std::make_pair(tx_count, std::move(sdu_copy)));
|
|
|
|
undelivered_sdus_queue.insert(std::make_pair(sn, std::move(sdu_copy)));
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|