diff --git a/lib/include/srslte/interfaces/pdcp_interface_types.h b/lib/include/srslte/interfaces/pdcp_interface_types.h index cb84df668..a9bcf4f01 100644 --- a/lib/include/srslte/interfaces/pdcp_interface_types.h +++ b/lib/include/srslte/interfaces/pdcp_interface_types.h @@ -43,6 +43,13 @@ const uint8_t PDCP_SN_LEN_18 = 18; typedef enum { PDCP_RB_IS_SRB, PDCP_RB_IS_DRB } pdcp_rb_type_t; +enum pdcp_dc_field_t { + PDCP_DC_FIELD_CONTROL_PDU = 0, + PDCP_DC_FIELD_DATA_PDU, + PDCP_DC_FIELD_N_ITEMS, +}; +static const char* pdcp_dc_field_text[PDCP_DC_FIELD_N_ITEMS] = {"Control PDU", "Data PDU"}; + // Taken from PDCP-Config (TS 38.331 version 15.2.1) enum class pdcp_t_reordering_t { ms0 = 0, diff --git a/lib/include/srslte/upper/pdcp_entity_base.h b/lib/include/srslte/upper/pdcp_entity_base.h index e23c1c1fb..47e0d368a 100644 --- a/lib/include/srslte/upper/pdcp_entity_base.h +++ b/lib/include/srslte/upper/pdcp_entity_base.h @@ -158,6 +158,7 @@ protected: void cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t count, uint8_t* msg); // Common packing functions + bool is_control_pdu(const unique_byte_buffer_t& pdu); uint32_t read_data_header(const unique_byte_buffer_t& pdu); void discard_data_header(const unique_byte_buffer_t& pdu); void write_data_header(const srslte::unique_byte_buffer_t& sdu, uint32_t count); diff --git a/lib/src/upper/pdcp_entity_base.cc b/lib/src/upper/pdcp_entity_base.cc index fd6745922..ddfa8a9a2 100644 --- a/lib/src/upper/pdcp_entity_base.cc +++ b/lib/src/upper/pdcp_entity_base.cc @@ -27,8 +27,7 @@ namespace srslte { pdcp_entity_base::pdcp_entity_base(task_sched_handle task_sched_, srslte::log_ref log_) : - log(log_), - task_sched(task_sched_) + log(log_), task_sched(task_sched_) {} pdcp_entity_base::~pdcp_entity_base() {} @@ -218,6 +217,13 @@ void pdcp_entity_base::cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t cou /**************************************************************************** * Common pack functions ***************************************************************************/ + +bool pdcp_entity_base::is_control_pdu(const unique_byte_buffer_t& pdu) +{ + const uint8_t* payload = pdu->msg; + return ((*(payload) >> 7) & 0x01) == PDCP_DC_FIELD_CONTROL_PDU; +} + uint32_t pdcp_entity_base::read_data_header(const unique_byte_buffer_t& pdu) { // Check PDU is long enough to extract header @@ -273,7 +279,7 @@ void pdcp_entity_base::write_data_header(const srslte::unique_byte_buffer_t& sdu sdu->msg[0] = SN(count); // Data PDU and SN LEN 5 implies SRB, D flag must not be present break; case PDCP_SN_LEN_7: - sdu->msg[0] = SN(count); + sdu->msg[0] = SN(count); if (is_drb()) { sdu->msg[0] |= 0x80; // On Data PDUs for DRBs we must set the D flag. } diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index 7dba5b8b6..410e0727b 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -31,10 +31,7 @@ pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_, srslte::log_ref log_, uint32_t lcid_, pdcp_config_t cfg_) : - pdcp_entity_base(task_sched_, log_), - rlc(rlc_), - rrc(rrc_), - gw(gw_) + pdcp_entity_base(task_sched_, log_), rlc(rlc_), rrc(rrc_), gw(gw_) { lcid = lcid_; cfg = cfg_; @@ -161,6 +158,12 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu) // RLC interface void pdcp_entity_lte::write_pdu(unique_byte_buffer_t pdu) { + // drop control PDUs + if (is_drb() && is_control_pdu(pdu)) { + log->info("Dropping PDCP control PDU\n"); + return; + } + // Sanity check if (pdu->N_bytes <= cfg.hdr_len_bytes) { log->error("PDCP PDU smaller than required header size.\n");