diff --git a/lib/include/srslte/interfaces/enb_interfaces.h b/lib/include/srslte/interfaces/enb_interfaces.h index 8e0c35ed6..aba3ca9d7 100644 --- a/lib/include/srslte/interfaces/enb_interfaces.h +++ b/lib/include/srslte/interfaces/enb_interfaces.h @@ -20,7 +20,6 @@ namespace srsenb { class stack_interface_phy_lte; - class stack_interface_s1ap_lte { public: diff --git a/lib/include/srslte/interfaces/enb_pdcp_interfaces.h b/lib/include/srslte/interfaces/enb_pdcp_interfaces.h index 05ffe1749..572436c9f 100644 --- a/lib/include/srslte/interfaces/enb_pdcp_interfaces.h +++ b/lib/include/srslte/interfaces/enb_pdcp_interfaces.h @@ -40,6 +40,7 @@ public: virtual void config_security(uint16_t rnti, uint32_t lcid, srslte::as_security_config_t sec_cfg) = 0; virtual void enable_integrity(uint16_t rnti, uint32_t lcid) = 0; virtual void enable_encryption(uint16_t rnti, uint32_t lcid) = 0; + virtual void send_status_report(uint16_t rnti, uint32_t lcid) = 0; virtual bool get_bearer_state(uint16_t rnti, uint32_t lcid, srslte::pdcp_lte_state_t* state) = 0; virtual bool set_bearer_state(uint16_t rnti, uint32_t lcid, const srslte::pdcp_lte_state_t& state) = 0; virtual void reestablish(uint16_t rnti) = 0; diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index a90db0cdc..3d561e5fa 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -267,6 +267,7 @@ public: virtual void enable_integrity(uint32_t lcid, srslte::srslte_direction_t direction) = 0; virtual void enable_encryption(uint32_t lcid, srslte::srslte_direction_t direction = srslte::srslte_direction_t::DIRECTION_TXRX) = 0; + virtual void send_status_report(uint32_t lcid) = 0; }; // RRC NR interface for RRC (LTE) class rrc_nr_interface_rrc diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 4f075f747..143aad3c7 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -49,6 +49,7 @@ public: void enable_security_timed(uint32_t lcid, srslte_direction_t direction, uint32_t sn); bool get_bearer_state(uint32_t lcid, srslte::pdcp_lte_state_t* state); bool set_bearer_state(uint32_t lcid, const srslte::pdcp_lte_state_t& state); + void send_status_report(uint32_t lcid) override; // RLC interface void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu) override; diff --git a/lib/include/srslte/upper/pdcp_entity_base.h b/lib/include/srslte/upper/pdcp_entity_base.h index bd71b5046..111ba0d66 100644 --- a/lib/include/srslte/upper/pdcp_entity_base.h +++ b/lib/include/srslte/upper/pdcp_entity_base.h @@ -118,6 +118,8 @@ public: virtual std::map get_buffered_pdus() = 0; + virtual void send_status_report() = 0; + // COUNT, HFN and SN helpers uint32_t HFN(uint32_t count); uint32_t SN(uint32_t count); diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index eb45fb448..80ef0e4c6 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -65,7 +65,7 @@ public: std::map get_buffered_pdus() override; // Status report helper(s) - bool send_status_report(); + void send_status_report(); void handle_status_report_pdu(srslte::unique_byte_buffer_t pdu); // Internal state getters/setters diff --git a/lib/include/srslte/upper/pdcp_entity_nr.h b/lib/include/srslte/upper/pdcp_entity_nr.h index 66e3ddb75..fd02e3cc6 100644 --- a/lib/include/srslte/upper/pdcp_entity_nr.h +++ b/lib/include/srslte/upper/pdcp_entity_nr.h @@ -60,6 +60,8 @@ public: void get_bearer_state(pdcp_lte_state_t* state) override; void set_bearer_state(const pdcp_lte_state_t& state) override; + void send_status_report() override {} + std::map get_buffered_pdus() override { return {}; } // State variable getters (useful for testing) diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 691f5e8bf..53fb15df1 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -221,6 +221,13 @@ void pdcp::enable_security_timed(uint32_t lcid, srslte_direction_t direction, ui } } +void pdcp::send_status_report(uint32_t lcid) +{ + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->send_status_report(); + } +} + bool pdcp::get_bearer_state(uint32_t lcid, srslte::pdcp_lte_state_t* state) { if (not valid_lcid(lcid)) { diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index e8475899f..67fe3e17e 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -82,7 +82,8 @@ void pdcp_entity_lte::reestablish() st.rx_hfn = 0; st.next_pdcp_rx_sn = 0; } else { - // TODO Send status report if required on reestablishment in RLC AM + // Send status report if required on reestablishment in RLC AM + send_status_report(); } } @@ -392,12 +393,12 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu) ***************************************************************************/ // Section 5.3.1 transmit operation -bool pdcp_entity_lte::send_status_report() +void pdcp_entity_lte::send_status_report() { // Check wether RLC AM is being used. if (rlc->rb_is_um(lcid)) { logger.error("Trying to send PDCP Status Report and RLC is not AM"); - return false; + return; } // Get First Missing Segment (FMS) @@ -414,7 +415,7 @@ bool pdcp_entity_lte::send_status_report() unique_byte_buffer_t pdu = make_byte_buffer(); if (pdu == nullptr) { logger.error("Error allocating buffer for status report"); - return false; + return; } // Set control bit and type of PDU @@ -435,7 +436,7 @@ bool pdcp_entity_lte::send_status_report() break; default: logger.error("Unsupported SN length for Status Report."); - return false; + return; } // Add bitmap of missing PDUs, if necessary @@ -461,12 +462,14 @@ bool pdcp_entity_lte::send_status_report() // Write PDU to RLC rlc->write_sdu(lcid, std::move(pdu)); - return true; + return; } // Section 5.3.2 receive operation void pdcp_entity_lte::handle_status_report_pdu(unique_byte_buffer_t pdu) { + logger.info("Handling Status Report PDU. Size=%ld", pdu->N_bytes); + uint32_t fms; std::vector acked_sns; uint32_t bitmap_offset; diff --git a/srsenb/hdr/stack/upper/pdcp.h b/srsenb/hdr/stack/upper/pdcp.h index d8045d4e1..5f2a17d48 100644 --- a/srsenb/hdr/stack/upper/pdcp.h +++ b/srsenb/hdr/stack/upper/pdcp.h @@ -51,6 +51,7 @@ public: void enable_encryption(uint16_t rnti, uint32_t lcid) override; bool get_bearer_state(uint16_t rnti, uint32_t lcid, srslte::pdcp_lte_state_t* state) override; bool set_bearer_state(uint16_t rnti, uint32_t lcid, const srslte::pdcp_lte_state_t& state) override; + void send_status_report(uint16_t rnti, uint32_t lcid) override; void reestablish(uint16_t rnti) override; // pdcp_interface_gtpu diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 54685532c..2fc4ee4f7 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -1213,6 +1213,8 @@ void rrc::ue::apply_pdcp_drb_updates(const rr_cfg_ded_s& pending_rr_cfg) bool is_am = parent->cfg.qci_cfg[erab_pair.second.qos_params.qci].rlc_cfg.type().value == asn1::rrc::rlc_cfg_c::types_opts::am; if (is_am) { + bool is_status_report_required = + parent->cfg.qci_cfg[erab_pair.second.qos_params.qci].pdcp_cfg.rlc_am.status_report_required; parent->logger.debug("Set PDCP state: TX HFN %d, NEXT_PDCP_TX_SN %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, " "LAST_SUBMITTED_PDCP_RX_SN %d", old_reest_pdcp_state[lcid].tx_hfn, @@ -1221,6 +1223,10 @@ void rrc::ue::apply_pdcp_drb_updates(const rr_cfg_ded_s& pending_rr_cfg) old_reest_pdcp_state[lcid].next_pdcp_rx_sn, old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn); parent->pdcp->set_bearer_state(rnti, lcid, old_reest_pdcp_state[lcid]); + parent->pdcp->set_bearer_state(rnti, lcid, old_reest_pdcp_state[lcid]); + if (is_status_report_required) { + parent->pdcp->send_status_report(rnti, lcid); + } } } } diff --git a/srsenb/src/stack/upper/pdcp.cc b/srsenb/src/stack/upper/pdcp.cc index 820d05443..ab833cb2f 100644 --- a/srsenb/src/stack/upper/pdcp.cc +++ b/srsenb/src/stack/upper/pdcp.cc @@ -135,20 +135,12 @@ void pdcp::reestablish(uint16_t rnti) users[rnti].pdcp->reestablish(); } -void pdcp::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) -{ - if (users.count(rnti)) { - users[rnti].pdcp->write_pdu(lcid, std::move(sdu)); - } -} - void pdcp::notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) { if (users.count(rnti)) { users[rnti].pdcp->notify_delivery(lcid, pdcp_sns); } } - void pdcp::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu, int pdcp_sn) { if (users.count(rnti)) { @@ -161,6 +153,13 @@ void pdcp::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t } } +void pdcp::send_status_report(uint16_t rnti, uint32_t lcid) +{ + if (users.count(rnti)) { + users[rnti].pdcp->send_status_report(lcid); + } +} + std::map pdcp::get_buffered_pdus(uint16_t rnti, uint32_t lcid) { if (users.count(rnti)) { @@ -169,6 +168,13 @@ std::map pdcp::get_buffered_pdus(uint16_ return {}; } +void pdcp::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) +{ + if (users.count(rnti)) { + users[rnti].pdcp->write_pdu(lcid, std::move(sdu)); + } +} + void pdcp::user_interface_gtpu::write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) { gtpu->write_pdu(rnti, lcid, std::move(pdu)); diff --git a/srsenb/test/common/dummy_classes.h b/srsenb/test/common/dummy_classes.h index 80a205c09..12ba47f41 100644 --- a/srsenb/test/common/dummy_classes.h +++ b/srsenb/test/common/dummy_classes.h @@ -76,6 +76,7 @@ public: bool get_bearer_state(uint16_t rnti, uint32_t lcid, srslte::pdcp_lte_state_t* state) override { return true; } bool set_bearer_state(uint16_t rnti, uint32_t lcid, const srslte::pdcp_lte_state_t& state) override { return true; } void reestablish(uint16_t rnti) override {} + void send_status_report(uint16_t rnti, uint32_t lcid) override {} std::map get_buffered_pdus(uint16_t rnti, uint32_t lcid) override { return {}; diff --git a/srsenb/test/upper/gtpu_test.cc b/srsenb/test/upper/gtpu_test.cc index 0efefa671..2e3aafd6a 100644 --- a/srsenb/test/upper/gtpu_test.cc +++ b/srsenb/test/upper/gtpu_test.cc @@ -47,6 +47,8 @@ public: { return std::move(buffered_pdus); } + void send_status_report(uint16_t rnti, uint32_t lcid) override {} + void push_buffered_pdu(uint32_t sn, srslte::unique_byte_buffer_t pdu) { buffered_pdus[sn] = std::move(pdu); } void clear() diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index ef602b763..19f73532d 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -957,8 +957,8 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc:: rrc_ptr->reestablishment_successful = false; for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) { if (rrc_ptr->rlc->has_bearer(i)) { - rrc_ptr->pdcp->reestablish(i); rrc_ptr->rlc->reestablish(i); + rrc_ptr->pdcp->reestablish(i); } } } @@ -969,6 +969,7 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc:: return proc_outcome_t::error; } } + // Apply Scell RR configurations (call is non-blocking). Make a copy since can be changed inside // apply_scell_config() Note that apply_scell_config() calls set_scell() and set_config() which run in the // background. @@ -1323,9 +1324,9 @@ proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause) reest_cellid = rrc_ptr->meas_cells.find_cell(reest_source_freq, reest_source_pci)->get_cell_id(); Info("Starting... cause: \"%s\", UE context: {C-RNTI=0x%x, PCI=%d, CELL ID=%d}", - reest_cause == asn1::rrc::reest_cause_opts::recfg_fail - ? "Reconfiguration failure" - : cause == asn1::rrc::reest_cause_opts::ho_fail ? "Handover failure" : "Other failure", + reest_cause == asn1::rrc::reest_cause_opts::recfg_fail ? "Reconfiguration failure" + : cause == asn1::rrc::reest_cause_opts::ho_fail ? "Handover failure" + : "Other failure", reest_rnti, reest_source_pci, reest_cellid);