diff --git a/lib/include/srslte/interfaces/enb_interfaces.h b/lib/include/srslte/interfaces/enb_interfaces.h index 4dd64f6b5..067144cf3 100644 --- a/lib/include/srslte/interfaces/enb_interfaces.h +++ b/lib/include/srslte/interfaces/enb_interfaces.h @@ -385,7 +385,8 @@ public: virtual void enable_integrity(uint16_t rnti, uint32_t lcid) = 0; virtual void enable_encryption(uint16_t rnti, uint32_t lcid) = 0; virtual bool - get_bearer_status(uint16_t rnti, uint32_t lcid, uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn) = 0; + get_bearer_status(uint16_t rnti, uint32_t lcid, uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn) = 0; + virtual bool get_state(uint16_t rnti, uint32_t lcid, srslte::pdcp_lte_state_t* state) = 0; }; // PDCP interface for RLC diff --git a/lib/include/srslte/interfaces/pdcp_interface_types.h b/lib/include/srslte/interfaces/pdcp_interface_types.h index 5b6dd9c72..468b2192f 100644 --- a/lib/include/srslte/interfaces/pdcp_interface_types.h +++ b/lib/include/srslte/interfaces/pdcp_interface_types.h @@ -142,6 +142,14 @@ public: enum srslte_direction_t { DIRECTION_NONE = 0, DIRECTION_TX, DIRECTION_RX, DIRECTION_TXRX, DIRECTION_N_ITEMS }; static const char* srslte_direction_text[DIRECTION_N_ITEMS] = {"none", "tx", "rx", "tx/rx"}; +// PDCP LTE internal state +struct pdcp_lte_state_t { + uint32_t tx_count; + uint32_t rx_hfn; + uint32_t next_pdcp_rx_sn; + uint32_t last_submitted_pdcp_rx_sn; +}; + } // namespace srslte #endif // SRSLTE_PDCP_INTERFACE_TYPES_H diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index d3477d1a3..ad0505584 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -56,6 +56,7 @@ public: void enable_encryption(uint32_t lcid, srslte_direction_t direction); void enable_security_timed(uint32_t lcid, srslte_direction_t direction, uint32_t sn); bool get_bearer_status(uint32_t lcid, uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn); + bool get_state(uint32_t lcid, srslte::pdcp_lte_state_t* state); // RLC interface void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu); diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index d867664ff..0903dd4e3 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -39,13 +39,6 @@ namespace srslte { #define PDCP_CONTROL_MAC_I 0x00000000 -struct pdcp_lte_state_t { - uint32_t tx_count; - uint32_t rx_hfn; - uint32_t next_pdcp_rx_sn; - uint32_t last_submitted_pdcp_rx_sn; -}; - /**************************************************************************** * LTE PDCP Entity * Class for LTE PDCP entities @@ -64,10 +57,10 @@ public: void reestablish(); // GW/RRC interface - void write_sdu(unique_byte_buffer_t sdu, bool blocking); - void get_bearer_status(uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn); - pdcp_lte_state_t get_state(); - void set_state(const pdcp_lte_state_t& state); + void write_sdu(unique_byte_buffer_t sdu, bool blocking); + void get_bearer_status(uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn); + void get_state(pdcp_lte_state_t* state); + void set_state(const pdcp_lte_state_t& state); // RLC interface void write_pdu(unique_byte_buffer_t pdu); diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 88deaa5df..99da4f4dd 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -24,10 +24,8 @@ namespace srslte { pdcp::pdcp(srslte::task_handler_interface* task_executor_, const char* logname) : - task_executor(task_executor_), - pdcp_log(logname) -{ -} + task_executor(task_executor_), pdcp_log(logname) +{} pdcp::~pdcp() { @@ -230,6 +228,15 @@ bool pdcp::get_bearer_status(uint32_t lcid, uint16_t* dlsn, uint16_t* dlhfn, uin return true; } +bool pdcp::get_state(uint32_t lcid, srslte::pdcp_lte_state_t* state) +{ + if (not valid_lcid(lcid)) { + return false; + } + pdcp_array[lcid]->get_state(state); + return true; +} + /******************************************************************************* RLC interface *******************************************************************************/ diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index 6fbc65c80..47337d580 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -369,9 +369,9 @@ bool pdcp_entity_lte::check_valid_config() /**************************************************************************** * Internal state getters/setters ***************************************************************************/ -pdcp_lte_state_t pdcp_entity_lte::get_state() +void pdcp_entity_lte::get_state(pdcp_lte_state_t* state) { - return pdcp_lte_state_t{tx_count, rx_hfn, next_pdcp_rx_sn, last_submitted_pdcp_rx_sn}; + *state = {tx_count, rx_hfn, next_pdcp_rx_sn, last_submitted_pdcp_rx_sn}; } void pdcp_entity_lte::set_state(const pdcp_lte_state_t& state) diff --git a/srsenb/hdr/stack/rrc/rrc_ue.h b/srsenb/hdr/stack/rrc/rrc_ue.h index d389b0ba4..6c9b4da71 100644 --- a/srsenb/hdr/stack/rrc/rrc_ue.h +++ b/srsenb/hdr/stack/rrc/rrc_ue.h @@ -123,8 +123,9 @@ private: sched_interface::ue_cfg_t current_sched_ue_cfg = {}; uint32_t rlf_cnt = 0; uint8_t transaction_id = 0; - uint16_t old_reest_rnti = SRSLTE_INVALID_RNTI; rrc_state_t state = RRC_STATE_IDLE; + uint16_t old_reest_rnti = SRSLTE_INVALID_RNTI; + srslte::pdcp_lte_state_t old_reest_pdcp_state = {}; asn1::s1ap::ue_aggregate_maximum_bitrate_s bitrates; bool eutra_capabilities_unpacked = false; diff --git a/srsenb/hdr/stack/upper/pdcp.h b/srsenb/hdr/stack/upper/pdcp.h index 33e360359..62aec899a 100644 --- a/srsenb/hdr/stack/upper/pdcp.h +++ b/srsenb/hdr/stack/upper/pdcp.h @@ -54,6 +54,7 @@ public: void enable_encryption(uint16_t rnti, uint32_t lcid) override; bool get_bearer_status(uint16_t rnti, uint32_t lcid, uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn) override; + bool get_state(uint16_t rnti, uint32_t lcid, srslte::pdcp_lte_state_t* state); private: class user_interface_rlc : public srsue::rlc_interface_pdcp diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 1a79e6e04..1ae3d34d2 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -364,6 +364,9 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) // Modify GTP-U tunnel parent->gtpu->mod_bearer_rnti(old_rnti, rnti); + // Get PDCP entity state (required when using RLC AM) + parent->pdcp->get_state(old_rnti, 3, &old_reest_pdcp_state); + old_reest_rnti = old_rnti; state = RRC_STATE_WAIT_FOR_CON_REEST_COMPLETE; set_activity_timeout(UE_RESPONSE_RX_TIMEOUT); diff --git a/srsenb/src/stack/upper/pdcp.cc b/srsenb/src/stack/upper/pdcp.cc index 989aa9721..9a45ffbe6 100644 --- a/srsenb/src/stack/upper/pdcp.cc +++ b/srsenb/src/stack/upper/pdcp.cc @@ -25,9 +25,7 @@ namespace srsenb { pdcp::pdcp(srslte::task_handler_interface* task_executor_, const char* logname) : - task_executor(task_executor_), - log_h(logname), - pool(srslte::byte_buffer_pool::get_instance()) + task_executor(task_executor_), log_h(logname), pool(srslte::byte_buffer_pool::get_instance()) {} void pdcp::init(rlc_interface_pdcp* rlc_, rrc_interface_pdcp* rrc_, gtpu_interface_pdcp* gtpu_) @@ -132,6 +130,14 @@ bool pdcp::get_bearer_status(uint16_t rnti, return users[rnti].pdcp->get_bearer_status(lcid, dlsn, dlhfn, ulsn, ulhfn); } +bool pdcp::get_state(uint16_t rnti, uint32_t lcid, srslte::pdcp_lte_state_t* state) +{ + if (users.count(rnti) == 0) { + return false; + } + return users[rnti].pdcp->get_state(lcid, state); +} + void pdcp::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) { if (users.count(rnti)) { diff --git a/srsenb/test/common/dummy_classes.h b/srsenb/test/common/dummy_classes.h index f3e38f9a8..d2272bf95 100644 --- a/srsenb/test/common/dummy_classes.h +++ b/srsenb/test/common/dummy_classes.h @@ -77,6 +77,7 @@ public: { return true; } + bool get_state(uint16_t rnti, uint32_t lcid, srslte::pdcp_lte_state_t* state) { return true; } }; class s1ap_dummy : public s1ap_interface_rrc