diff --git a/lib/include/srslte/interfaces/pdcp_interface_types.h b/lib/include/srslte/interfaces/pdcp_interface_types.h index ecc215635..cb84df668 100644 --- a/lib/include/srslte/interfaces/pdcp_interface_types.h +++ b/lib/include/srslte/interfaces/pdcp_interface_types.h @@ -144,7 +144,8 @@ static const char* srslte_direction_text[DIRECTION_N_ITEMS] = {"none", "tx", "rx // PDCP LTE internal state variables, as defined in TS 36 323, section 7.1 struct pdcp_lte_state_t { - uint32_t tx_count; + uint32_t next_pdcp_tx_sn; + uint32_t tx_hfn; uint32_t rx_hfn; uint32_t next_pdcp_rx_sn; uint32_t last_submitted_pdcp_rx_sn; diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index ebd7480fb..5b9088d63 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -52,7 +52,8 @@ void pdcp_entity_lte::init(uint32_t lcid_, pdcp_config_t cfg_) reordering_window = 2048; } - st.tx_count = 0; + st.next_pdcp_tx_sn = 0; + st.tx_hfn = 0; st.rx_hfn = 0; st.next_pdcp_rx_sn = 0; maximum_pdcp_sn = (1 << cfg.sn_len) - 1; @@ -77,13 +78,15 @@ void pdcp_entity_lte::reestablish() log->info("Re-establish %s with bearer ID: %d\n", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id); // For SRBs if (is_srb()) { - st.tx_count = 0; + st.next_pdcp_tx_sn = 0; + st.tx_hfn = 0; st.rx_hfn = 0; st.next_pdcp_rx_sn = 0; } else { // Only reset counter in RLC-UM if (rlc->rb_is_um(lcid)) { - st.tx_count = 0; + st.next_pdcp_tx_sn = 0; + st.tx_hfn = 0; st.rx_hfn = 0; st.next_pdcp_rx_sn = 0; } @@ -102,8 +105,11 @@ void pdcp_entity_lte::reset() // GW/RRC interface void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, bool blocking) { + // Get COUNT to be used with this packet + uint32_t tx_count = COUNT(st.tx_hfn, st.next_pdcp_tx_sn); + // check for pending security config in transmit direction - if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast(st.tx_count)) { + if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast(tx_count)) { enable_integrity(DIRECTION_TX); enable_encryption(DIRECTION_TX); enable_security_tx_sn = -1; @@ -113,17 +119,17 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, bool blocking) sdu->N_bytes, "TX %s SDU, SN=%d, integrity=%s, encryption=%s", rrc->get_rb_name(lcid).c_str(), - st.tx_count, + tx_count, srslte_direction_text[integrity_direction], srslte_direction_text[encryption_direction]); - write_data_header(sdu, st.tx_count); + write_data_header(sdu, tx_count); // Append MAC (SRBs only) uint8_t mac[4] = {}; bool do_integrity = integrity_direction == DIRECTION_TX || integrity_direction == DIRECTION_TXRX; if (do_integrity && is_srb()) { - integrity_generate(sdu->msg, sdu->N_bytes, st.tx_count, mac); + integrity_generate(sdu->msg, sdu->N_bytes, tx_count, mac); } if (is_srb()) { @@ -132,10 +138,16 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, bool blocking) if (encryption_direction == DIRECTION_TX || encryption_direction == DIRECTION_TXRX) { cipher_encrypt( - &sdu->msg[cfg.hdr_len_bytes], sdu->N_bytes - cfg.hdr_len_bytes, st.tx_count, &sdu->msg[cfg.hdr_len_bytes]); + &sdu->msg[cfg.hdr_len_bytes], sdu->N_bytes - cfg.hdr_len_bytes, tx_count, &sdu->msg[cfg.hdr_len_bytes]); log->info_hex(sdu->msg, sdu->N_bytes, "TX %s SDU (encrypted)", rrc->get_rb_name(lcid).c_str()); } - st.tx_count++; + + // Incremente NEXT_PDCP_TX_SN and TX_HFN + st.next_pdcp_tx_sn++; + if (st.next_pdcp_tx_sn > maximum_pdcp_sn) { + st.tx_hfn++; + st.next_pdcp_tx_sn = 0; + } rlc->write_sdu(lcid, std::move(sdu), blocking); } @@ -328,18 +340,8 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu) ***************************************************************************/ void pdcp_entity_lte::get_bearer_status(uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn) { - if (cfg.rb_type == PDCP_RB_IS_DRB) { - if (12 == cfg.sn_len) { - *dlsn = (uint16_t)(st.tx_count & 0xFFFu); - *dlhfn = (uint16_t)((st.tx_count - *dlsn) >> 12u); - } else { - *dlsn = (uint16_t)(st.tx_count & 0x7Fu); - *dlhfn = (uint16_t)((st.tx_count - *dlsn) >> 7u); - } - } else { // is control - *dlsn = (uint16_t)(st.tx_count & 0x1Fu); - *dlhfn = (uint16_t)((st.tx_count - *dlsn) >> 5u); - } + *dlsn = (uint16_t)st.next_pdcp_tx_sn; + *dlhfn = (uint16_t)st.tx_hfn; *ulsn = (uint16_t)st.next_pdcp_rx_sn; *ulhfn = (uint16_t)st.rx_hfn; } diff --git a/lib/test/upper/pdcp_lte_test.h b/lib/test/upper/pdcp_lte_test.h index 89aa2c2c4..3c5455f89 100644 --- a/lib/test/upper/pdcp_lte_test.h +++ b/lib/test/upper/pdcp_lte_test.h @@ -108,7 +108,8 @@ srslte::unique_byte_buffer_t gen_expected_pdu(const srslte::unique_byte_buffer_t rlc_dummy* rlc = &pdcp_hlp.rlc; srslte::pdcp_lte_state_t init_state = {}; - init_state.tx_count = count; + init_state.tx_hfn = pdcp->HFN(count); + init_state.next_pdcp_tx_sn = pdcp->SN(count); pdcp_hlp.set_pdcp_initial_state(init_state); srslte::unique_byte_buffer_t sdu = srslte::allocate_unique_buffer(*pool); diff --git a/lib/test/upper/pdcp_lte_test_rx.cc b/lib/test/upper/pdcp_lte_test_rx.cc index 6dfaee256..b70916a91 100644 --- a/lib/test/upper/pdcp_lte_test_rx.cc +++ b/lib/test/upper/pdcp_lte_test_rx.cc @@ -97,7 +97,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) std::vector test1_pdus = gen_expected_pdus_vector( tst_sdu1, test1_counts, srslte::PDCP_SN_LEN_5, srslte::PDCP_RB_IS_SRB, sec_cfg, pool, log); srslte::pdcp_lte_state_t test1_init_state = { - .tx_count = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 31, .last_submitted_pdcp_rx_sn = 30}; + .next_pdcp_tx_sn = 0, .tx_hfn = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 31, .last_submitted_pdcp_rx_sn = 30}; TESTASSERT(test_rx(std::move(test1_pdus), test1_init_state, srslte::PDCP_SN_LEN_5, @@ -119,7 +119,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) std::vector test_pdus = gen_expected_pdus_vector( tst_sdu1, test_counts, srslte::PDCP_SN_LEN_12, srslte::PDCP_RB_IS_DRB, sec_cfg, pool, log); srslte::pdcp_lte_state_t test_init_state = { - .tx_count = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 4095, .last_submitted_pdcp_rx_sn = 4094}; + .next_pdcp_tx_sn = 0, .tx_hfn = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 4095, .last_submitted_pdcp_rx_sn = 4094}; TESTASSERT(test_rx(std::move(test_pdus), test_init_state, srslte::PDCP_SN_LEN_12, @@ -140,7 +140,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) std::vector test_pdus = gen_expected_pdus_vector( tst_sdu1, test_counts, srslte::PDCP_SN_LEN_12, srslte::PDCP_RB_IS_DRB, sec_cfg, pool, log); srslte::pdcp_lte_state_t test_init_state = { - .tx_count = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 32, .last_submitted_pdcp_rx_sn = 31}; + .next_pdcp_tx_sn = 0, .tx_hfn = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 32, .last_submitted_pdcp_rx_sn = 31}; TESTASSERT(test_rx(std::move(test_pdus), test_init_state, srslte::PDCP_SN_LEN_12, diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index f5f6e2078..4c8c59dec 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -371,12 +371,13 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) parent->pdcp->get_state(old_rnti, lcid, &old_reest_pdcp_state[lcid]); parent->rrc_log->debug("Getting PDCP state for E-RAB with LCID %d\n", lcid); - parent->rrc_log->debug( - "Got PDCP state: TX COUNT %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, LAST_SUBMITTED_PDCP_RX_SN %d\n", - old_reest_pdcp_state[lcid].tx_count, - old_reest_pdcp_state[lcid].rx_hfn, - old_reest_pdcp_state[lcid].next_pdcp_rx_sn, - old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn); + parent->rrc_log->debug("Got PDCP state: TX HFN %d, NEXT_PDCP_TX_SN %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, " + "LAST_SUBMITTED_PDCP_RX_SN %d\n", + old_reest_pdcp_state[lcid].tx_hfn, + old_reest_pdcp_state[lcid].next_pdcp_tx_sn, + old_reest_pdcp_state[lcid].rx_hfn, + old_reest_pdcp_state[lcid].next_pdcp_rx_sn, + old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn); } old_reest_rnti = old_rnti; @@ -568,12 +569,13 @@ void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu) 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) { - parent->rrc_log->debug( - "Set PDCP state: TX COUNT %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, LAST_SUBMITTED_PDCP_RX_SN %d\n", - old_reest_pdcp_state[lcid].tx_count, - old_reest_pdcp_state[lcid].rx_hfn, - old_reest_pdcp_state[lcid].next_pdcp_rx_sn, - old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn); + parent->rrc_log->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\n", + old_reest_pdcp_state[lcid].tx_hfn, + old_reest_pdcp_state[lcid].next_pdcp_tx_sn, + old_reest_pdcp_state[lcid].rx_hfn, + old_reest_pdcp_state[lcid].next_pdcp_rx_sn, + old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn); parent->pdcp->set_state(rnti, lcid, old_reest_pdcp_state[lcid]); } }