Passing SN provided by upper layers to PDCP entity. Using it to calculate TX_COUNT if passed.

This commit is contained in:
Pedro Alvarez 2021-02-11 18:01:14 +00:00
parent 4789860bdd
commit dd6d6f731d
10 changed files with 33 additions and 24 deletions

View File

@ -83,10 +83,10 @@ public:
uint8_t pdn_type, uint8_t pdn_type,
uint32_t ip_addr, uint32_t ip_addr,
uint8_t* ipv6_if_id, uint8_t* ipv6_if_id,
char* err_str) = 0; char* err_str) = 0;
virtual int apply_traffic_flow_template(const uint8_t& eps_bearer_id, virtual int apply_traffic_flow_template(const uint8_t& eps_bearer_id,
const uint8_t& lcid, const uint8_t& lcid,
const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft) = 0; const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft) = 0;
typedef enum { typedef enum {
TEST_LOOP_INACTIVE = 0, TEST_LOOP_INACTIVE = 0,
@ -259,7 +259,7 @@ public:
virtual void reestablish() = 0; virtual void reestablish() = 0;
virtual void reestablish(uint32_t lcid) = 0; virtual void reestablish(uint32_t lcid) = 0;
virtual void reset() = 0; virtual void reset() = 0;
virtual void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; virtual void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, int sn = -1) = 0;
virtual void add_bearer(uint32_t lcid, srslte::pdcp_config_t cnfg) = 0; virtual void add_bearer(uint32_t lcid, srslte::pdcp_config_t cnfg) = 0;
virtual void change_lcid(uint32_t old_lcid, uint32_t new_lcid) = 0; virtual void change_lcid(uint32_t old_lcid, uint32_t new_lcid) = 0;
virtual void config_security(uint32_t lcid, srslte::as_security_config_t sec_cfg) = 0; virtual void config_security(uint32_t lcid, srslte::as_security_config_t sec_cfg) = 0;

View File

@ -36,7 +36,7 @@ public:
void reestablish() override; void reestablish() override;
void reestablish(uint32_t lcid) override; void reestablish(uint32_t lcid) override;
void reset() override; void reset() override;
void write_sdu(uint32_t lcid, unique_byte_buffer_t sdu) override; void write_sdu(uint32_t lcid, unique_byte_buffer_t sdu, int sn = -1) override;
void write_sdu_mch(uint32_t lcid, unique_byte_buffer_t sdu); void write_sdu_mch(uint32_t lcid, unique_byte_buffer_t sdu);
void add_bearer(uint32_t lcid, pdcp_config_t cnfg) override; void add_bearer(uint32_t lcid, pdcp_config_t cnfg) override;
void add_bearer_mrb(uint32_t lcid, pdcp_config_t cnfg); void add_bearer_mrb(uint32_t lcid, pdcp_config_t cnfg);

View File

@ -107,7 +107,7 @@ public:
void config_security(as_security_config_t sec_cfg_); void config_security(as_security_config_t sec_cfg_);
// GW/SDAP/RRC interface // GW/SDAP/RRC interface
virtual void write_sdu(unique_byte_buffer_t sdu) = 0; virtual void write_sdu(unique_byte_buffer_t sdu, int sn = -1) = 0;
// RLC interface // RLC interface
virtual void write_pdu(unique_byte_buffer_t pdu) = 0; virtual void write_pdu(unique_byte_buffer_t pdu) = 0;

View File

@ -49,7 +49,7 @@ public:
void reestablish() override; void reestablish() override;
// GW/RRC interface // GW/RRC interface
void write_sdu(unique_byte_buffer_t sdu) override; void write_sdu(unique_byte_buffer_t sdu, int sn = -1) override;
// RLC interface // RLC interface
void write_pdu(unique_byte_buffer_t pdu) override; void write_pdu(unique_byte_buffer_t pdu) override;

View File

@ -45,7 +45,7 @@ public:
void reestablish() final; void reestablish() final;
// RRC interface // RRC interface
void write_sdu(unique_byte_buffer_t sdu) final; void write_sdu(unique_byte_buffer_t sdu, int sn = -1) final;
// RLC interface // RLC interface
void write_pdu(unique_byte_buffer_t pdu) final; void write_pdu(unique_byte_buffer_t pdu) final;

View File

@ -76,10 +76,10 @@ bool pdcp::is_lcid_enabled(uint32_t lcid)
return valid_lcids_cached.count(lcid) > 0; return valid_lcids_cached.count(lcid) > 0;
} }
void pdcp::write_sdu(uint32_t lcid, unique_byte_buffer_t sdu) void pdcp::write_sdu(uint32_t lcid, unique_byte_buffer_t sdu, int sn)
{ {
if (valid_lcid(lcid)) { if (valid_lcid(lcid)) {
pdcp_array.at(lcid)->write_sdu(std::move(sdu)); pdcp_array.at(lcid)->write_sdu(std::move(sdu), sn);
} else { } else {
logger.warning("Writing sdu: lcid=%d. Deallocating sdu", lcid); logger.warning("Writing sdu: lcid=%d. Deallocating sdu", lcid);
} }

View File

@ -93,7 +93,7 @@ void pdcp_entity_lte::reset()
} }
// GW/RRC interface // GW/RRC interface
void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu) void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn)
{ {
if (rlc->sdu_queue_is_full(lcid)) { if (rlc->sdu_queue_is_full(lcid)) {
logger.info(sdu->msg, sdu->N_bytes, "Dropping %s SDU due to full queue", rrc->get_rb_name(lcid).c_str()); logger.info(sdu->msg, sdu->N_bytes, "Dropping %s SDU due to full queue", rrc->get_rb_name(lcid).c_str());
@ -101,7 +101,14 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu)
} }
// Get COUNT to be used with this packet // Get COUNT to be used with this packet
uint32_t tx_count = COUNT(st.tx_hfn, st.next_pdcp_tx_sn); uint32_t used_sn;
if (upper_sn == -1) {
used_sn = st.next_pdcp_tx_sn; // Normal scenario
} else {
used_sn = upper_sn; // SN provided by the upper layers, due to handover.
}
uint32_t tx_count = COUNT(st.tx_hfn, used_sn); // Normal scenario
// If the bearer is mapped to RLC AM, save TX_COUNT and a copy of the PDU. // If the bearer is mapped to RLC AM, save TX_COUNT and a copy of the PDU.
// This will be used for reestablishment, where unack'ed PDUs will be re-transmitted. // This will be used for reestablishment, where unack'ed PDUs will be re-transmitted.
@ -109,7 +116,7 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu)
// 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(st.next_pdcp_tx_sn, sdu); store_sdu(used_sn, sdu);
} }
// check for pending security config in transmit direction // check for pending security config in transmit direction
@ -124,11 +131,11 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu)
// Start discard timer // Start discard timer
if (cfg.discard_timer != pdcp_discard_timer_t::infinity) { if (cfg.discard_timer != pdcp_discard_timer_t::infinity) {
timer_handler::unique_timer discard_timer = task_sched.get_unique_timer(); timer_handler::unique_timer discard_timer = task_sched.get_unique_timer();
discard_callback discard_fnc(this, st.next_pdcp_tx_sn); discard_callback discard_fnc(this, used_sn);
discard_timer.set(static_cast<uint32_t>(cfg.discard_timer), discard_fnc); discard_timer.set(static_cast<uint32_t>(cfg.discard_timer), discard_fnc);
discard_timer.run(); discard_timer.run();
discard_timers_map.insert(std::make_pair(tx_count, std::move(discard_timer))); discard_timers_map.insert(std::make_pair(tx_count, std::move(discard_timer)));
logger.debug("Discard Timer set for SN %u. Timeout: %ums", tx_count, 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));
} }
// Append MAC (SRBs only) // Append MAC (SRBs only)
@ -151,18 +158,20 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu)
sdu->N_bytes, sdu->N_bytes,
"TX %s PDU, SN=%d, integrity=%s, encryption=%s", "TX %s PDU, SN=%d, integrity=%s, encryption=%s",
rrc->get_rb_name(lcid).c_str(), rrc->get_rb_name(lcid).c_str(),
st.next_pdcp_tx_sn, used_sn,
srslte_direction_text[integrity_direction], srslte_direction_text[integrity_direction],
srslte_direction_text[encryption_direction]); srslte_direction_text[encryption_direction]);
// Set SDU metadata for RLC AM // Set SDU metadata for RLC AM
sdu->md.pdcp_sn = st.next_pdcp_tx_sn; sdu->md.pdcp_sn = used_sn;
// Increment NEXT_PDCP_TX_SN and TX_HFN // Increment NEXT_PDCP_TX_SN and TX_HFN (only update variables if SN was not provided by upper layers)
st.next_pdcp_tx_sn++; if (upper_sn == -1) {
if (st.next_pdcp_tx_sn > maximum_pdcp_sn) { st.next_pdcp_tx_sn++;
st.tx_hfn++; if (st.next_pdcp_tx_sn > maximum_pdcp_sn) {
st.next_pdcp_tx_sn = 0; st.tx_hfn++;
st.next_pdcp_tx_sn = 0;
}
} }
// Pass PDU to lower layers // Pass PDU to lower layers

View File

@ -62,7 +62,7 @@ void pdcp_entity_nr::reset()
} }
// SDAP/RRC interface // SDAP/RRC interface
void pdcp_entity_nr::write_sdu(unique_byte_buffer_t sdu) void pdcp_entity_nr::write_sdu(unique_byte_buffer_t sdu, int sn)
{ {
// Log SDU // Log SDU
logger.info(sdu->msg, logger.info(sdu->msg,

View File

@ -151,7 +151,7 @@ void pdcp::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t
if (users.count(rnti)) { if (users.count(rnti)) {
if (rnti != SRSLTE_MRNTI) { if (rnti != SRSLTE_MRNTI) {
// TODO: Handle PDCP SN coming from GTPU // TODO: Handle PDCP SN coming from GTPU
users[rnti].pdcp->write_sdu(lcid, std::move(sdu)); users[rnti].pdcp->write_sdu(lcid, std::move(sdu), pdcp_sn);
} else { } else {
users[rnti].pdcp->write_sdu_mch(lcid, std::move(sdu)); users[rnti].pdcp->write_sdu_mch(lcid, std::move(sdu));
} }

View File

@ -194,7 +194,7 @@ class pdcp_test : public srslte::pdcp
{ {
public: public:
pdcp_test(const char* logname, srslte::task_sched_handle t) : srslte::pdcp(t, logname) {} pdcp_test(const char* logname, srslte::task_sched_handle t) : srslte::pdcp(t, logname) {}
void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) override void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, int sn = -1) override
{ {
ul_dcch_msg_s ul_dcch_msg; ul_dcch_msg_s ul_dcch_msg;
asn1::cbit_ref bref(sdu->msg, sdu->N_bytes); asn1::cbit_ref bref(sdu->msg, sdu->N_bytes);