Split PDCP tx_count state variable into tx_hfn and next_pdcp_tx_sn

variables.
master
Pedro Alvarez 5 years ago
parent 08578a7331
commit 208a539499

@ -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 // PDCP LTE internal state variables, as defined in TS 36 323, section 7.1
struct pdcp_lte_state_t { 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 rx_hfn;
uint32_t next_pdcp_rx_sn; uint32_t next_pdcp_rx_sn;
uint32_t last_submitted_pdcp_rx_sn; uint32_t last_submitted_pdcp_rx_sn;

@ -52,7 +52,8 @@ void pdcp_entity_lte::init(uint32_t lcid_, pdcp_config_t cfg_)
reordering_window = 2048; reordering_window = 2048;
} }
st.tx_count = 0; st.next_pdcp_tx_sn = 0;
st.tx_hfn = 0;
st.rx_hfn = 0; st.rx_hfn = 0;
st.next_pdcp_rx_sn = 0; st.next_pdcp_rx_sn = 0;
maximum_pdcp_sn = (1 << cfg.sn_len) - 1; 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); log->info("Re-establish %s with bearer ID: %d\n", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id);
// For SRBs // For SRBs
if (is_srb()) { if (is_srb()) {
st.tx_count = 0; st.next_pdcp_tx_sn = 0;
st.tx_hfn = 0;
st.rx_hfn = 0; st.rx_hfn = 0;
st.next_pdcp_rx_sn = 0; st.next_pdcp_rx_sn = 0;
} else { } else {
// Only reset counter in RLC-UM // Only reset counter in RLC-UM
if (rlc->rb_is_um(lcid)) { 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.rx_hfn = 0;
st.next_pdcp_rx_sn = 0; st.next_pdcp_rx_sn = 0;
} }
@ -102,8 +105,11 @@ void pdcp_entity_lte::reset()
// GW/RRC interface // GW/RRC interface
void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, bool blocking) 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 // check for pending security config in transmit direction
if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast<int32_t>(st.tx_count)) { if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast<int32_t>(tx_count)) {
enable_integrity(DIRECTION_TX); enable_integrity(DIRECTION_TX);
enable_encryption(DIRECTION_TX); enable_encryption(DIRECTION_TX);
enable_security_tx_sn = -1; 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, sdu->N_bytes,
"TX %s SDU, SN=%d, integrity=%s, encryption=%s", "TX %s SDU, SN=%d, integrity=%s, encryption=%s",
rrc->get_rb_name(lcid).c_str(), rrc->get_rb_name(lcid).c_str(),
st.tx_count, tx_count,
srslte_direction_text[integrity_direction], srslte_direction_text[integrity_direction],
srslte_direction_text[encryption_direction]); srslte_direction_text[encryption_direction]);
write_data_header(sdu, st.tx_count); write_data_header(sdu, tx_count);
// Append MAC (SRBs only) // Append MAC (SRBs only)
uint8_t mac[4] = {}; uint8_t mac[4] = {};
bool do_integrity = integrity_direction == DIRECTION_TX || integrity_direction == DIRECTION_TXRX; bool do_integrity = integrity_direction == DIRECTION_TX || integrity_direction == DIRECTION_TXRX;
if (do_integrity && is_srb()) { 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()) { 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) { if (encryption_direction == DIRECTION_TX || encryption_direction == DIRECTION_TXRX) {
cipher_encrypt( 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()); 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); 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) 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) { *dlsn = (uint16_t)st.next_pdcp_tx_sn;
if (12 == cfg.sn_len) { *dlhfn = (uint16_t)st.tx_hfn;
*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);
}
*ulsn = (uint16_t)st.next_pdcp_rx_sn; *ulsn = (uint16_t)st.next_pdcp_rx_sn;
*ulhfn = (uint16_t)st.rx_hfn; *ulhfn = (uint16_t)st.rx_hfn;
} }

@ -108,7 +108,8 @@ srslte::unique_byte_buffer_t gen_expected_pdu(const srslte::unique_byte_buffer_t
rlc_dummy* rlc = &pdcp_hlp.rlc; rlc_dummy* rlc = &pdcp_hlp.rlc;
srslte::pdcp_lte_state_t init_state = {}; 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); pdcp_hlp.set_pdcp_initial_state(init_state);
srslte::unique_byte_buffer_t sdu = srslte::allocate_unique_buffer(*pool); srslte::unique_byte_buffer_t sdu = srslte::allocate_unique_buffer(*pool);

@ -97,7 +97,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log)
std::vector<pdcp_test_event_t> test1_pdus = gen_expected_pdus_vector( std::vector<pdcp_test_event_t> test1_pdus = gen_expected_pdus_vector(
tst_sdu1, test1_counts, srslte::PDCP_SN_LEN_5, srslte::PDCP_RB_IS_SRB, sec_cfg, pool, log); 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 = { 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), TESTASSERT(test_rx(std::move(test1_pdus),
test1_init_state, test1_init_state,
srslte::PDCP_SN_LEN_5, srslte::PDCP_SN_LEN_5,
@ -119,7 +119,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log)
std::vector<pdcp_test_event_t> test_pdus = gen_expected_pdus_vector( std::vector<pdcp_test_event_t> test_pdus = gen_expected_pdus_vector(
tst_sdu1, test_counts, srslte::PDCP_SN_LEN_12, srslte::PDCP_RB_IS_DRB, sec_cfg, pool, log); 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 = { 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), TESTASSERT(test_rx(std::move(test_pdus),
test_init_state, test_init_state,
srslte::PDCP_SN_LEN_12, srslte::PDCP_SN_LEN_12,
@ -140,7 +140,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log)
std::vector<pdcp_test_event_t> test_pdus = gen_expected_pdus_vector( std::vector<pdcp_test_event_t> test_pdus = gen_expected_pdus_vector(
tst_sdu1, test_counts, srslte::PDCP_SN_LEN_12, srslte::PDCP_RB_IS_DRB, sec_cfg, pool, log); 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 = { 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), TESTASSERT(test_rx(std::move(test_pdus),
test_init_state, test_init_state,
srslte::PDCP_SN_LEN_12, srslte::PDCP_SN_LEN_12,

@ -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->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("Getting PDCP state for E-RAB with LCID %d\n", lcid);
parent->rrc_log->debug( parent->rrc_log->debug("Got PDCP state: TX HFN %d, NEXT_PDCP_TX_SN %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, "
"Got PDCP state: TX COUNT %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, LAST_SUBMITTED_PDCP_RX_SN %d\n", "LAST_SUBMITTED_PDCP_RX_SN %d\n",
old_reest_pdcp_state[lcid].tx_count, old_reest_pdcp_state[lcid].tx_hfn,
old_reest_pdcp_state[lcid].rx_hfn, old_reest_pdcp_state[lcid].next_pdcp_tx_sn,
old_reest_pdcp_state[lcid].next_pdcp_rx_sn, old_reest_pdcp_state[lcid].rx_hfn,
old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn); old_reest_pdcp_state[lcid].next_pdcp_rx_sn,
old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn);
} }
old_reest_rnti = old_rnti; 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 == 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; asn1::rrc::rlc_cfg_c::types_opts::am;
if (is_am) { if (is_am) {
parent->rrc_log->debug( parent->rrc_log->debug("Set PDCP state: TX HFN %d, NEXT_PDCP_TX_SN %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, "
"Set PDCP state: TX COUNT %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, LAST_SUBMITTED_PDCP_RX_SN %d\n", "LAST_SUBMITTED_PDCP_RX_SN %d\n",
old_reest_pdcp_state[lcid].tx_count, old_reest_pdcp_state[lcid].tx_hfn,
old_reest_pdcp_state[lcid].rx_hfn, old_reest_pdcp_state[lcid].next_pdcp_tx_sn,
old_reest_pdcp_state[lcid].next_pdcp_rx_sn, old_reest_pdcp_state[lcid].rx_hfn,
old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn); 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]); parent->pdcp->set_state(rnti, lcid, old_reest_pdcp_state[lcid]);
} }
} }

Loading…
Cancel
Save