|
|
@ -39,10 +39,10 @@ pdcp_entity_lte::~pdcp_entity_lte()
|
|
|
|
|
|
|
|
|
|
|
|
void pdcp_entity_lte::init(uint32_t lcid_, pdcp_config_t cfg_)
|
|
|
|
void pdcp_entity_lte::init(uint32_t lcid_, pdcp_config_t cfg_)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
lcid = lcid_;
|
|
|
|
lcid = lcid_;
|
|
|
|
cfg = cfg_;
|
|
|
|
cfg = cfg_;
|
|
|
|
active = true;
|
|
|
|
active = true;
|
|
|
|
tx_count = 0;
|
|
|
|
|
|
|
|
integrity_direction = DIRECTION_NONE;
|
|
|
|
integrity_direction = DIRECTION_NONE;
|
|
|
|
encryption_direction = DIRECTION_NONE;
|
|
|
|
encryption_direction = DIRECTION_NONE;
|
|
|
|
|
|
|
|
|
|
|
@ -52,10 +52,12 @@ void pdcp_entity_lte::init(uint32_t lcid_, pdcp_config_t cfg_)
|
|
|
|
reordering_window = 2048;
|
|
|
|
reordering_window = 2048;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rx_hfn = 0;
|
|
|
|
st.tx_count = 0;
|
|
|
|
next_pdcp_rx_sn = 0;
|
|
|
|
st.rx_hfn = 0;
|
|
|
|
maximum_pdcp_sn = (1 << cfg.sn_len) - 1;
|
|
|
|
st.next_pdcp_rx_sn = 0;
|
|
|
|
last_submitted_pdcp_rx_sn = maximum_pdcp_sn;
|
|
|
|
maximum_pdcp_sn = (1 << cfg.sn_len) - 1;
|
|
|
|
|
|
|
|
st.last_submitted_pdcp_rx_sn = maximum_pdcp_sn;
|
|
|
|
|
|
|
|
|
|
|
|
log->info("Init %s with bearer ID: %d\n", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id);
|
|
|
|
log->info("Init %s with bearer ID: %d\n", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id);
|
|
|
|
log->info("SN len bits: %d, SN len bytes: %d, reordering window: %d, Maximum SN %d\n",
|
|
|
|
log->info("SN len bits: %d, SN len bytes: %d, reordering window: %d, Maximum SN %d\n",
|
|
|
|
cfg.sn_len,
|
|
|
|
cfg.sn_len,
|
|
|
@ -75,15 +77,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()) {
|
|
|
|
tx_count = 0;
|
|
|
|
st.tx_count = 0;
|
|
|
|
rx_hfn = 0;
|
|
|
|
st.rx_hfn = 0;
|
|
|
|
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)) {
|
|
|
|
tx_count = 0;
|
|
|
|
st.tx_count = 0;
|
|
|
|
rx_hfn = 0;
|
|
|
|
st.rx_hfn = 0;
|
|
|
|
next_pdcp_rx_sn = 0;
|
|
|
|
st.next_pdcp_rx_sn = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -101,7 +103,7 @@ void pdcp_entity_lte::reset()
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// 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>(tx_count)) {
|
|
|
|
if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast<int32_t>(st.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;
|
|
|
@ -111,17 +113,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(),
|
|
|
|
tx_count,
|
|
|
|
st.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, tx_count);
|
|
|
|
write_data_header(sdu, st.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, tx_count, mac);
|
|
|
|
integrity_generate(sdu->msg, sdu->N_bytes, st.tx_count, mac);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (is_srb()) {
|
|
|
|
if (is_srb()) {
|
|
|
@ -130,10 +132,10 @@ 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, tx_count, &sdu->msg[cfg.hdr_len_bytes]);
|
|
|
|
&sdu->msg[cfg.hdr_len_bytes], sdu->N_bytes - cfg.hdr_len_bytes, st.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());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tx_count++;
|
|
|
|
st.tx_count++;
|
|
|
|
|
|
|
|
|
|
|
|
rlc->write_sdu(lcid, std::move(sdu), blocking);
|
|
|
|
rlc->write_sdu(lcid, std::move(sdu), blocking);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -187,14 +189,14 @@ void pdcp_entity_lte::handle_srb_pdu(srslte::unique_byte_buffer_t pdu)
|
|
|
|
// Read SN from header
|
|
|
|
// Read SN from header
|
|
|
|
uint32_t sn = read_data_header(pdu);
|
|
|
|
uint32_t sn = read_data_header(pdu);
|
|
|
|
|
|
|
|
|
|
|
|
log->debug("RX SRB PDU. Next_PDCP_RX_SN %d, SN %d", next_pdcp_rx_sn, sn);
|
|
|
|
log->debug("RX SRB PDU. Next_PDCP_RX_SN %d, SN %d", st.next_pdcp_rx_sn, sn);
|
|
|
|
|
|
|
|
|
|
|
|
// Estimate COUNT for integrity check and decryption
|
|
|
|
// Estimate COUNT for integrity check and decryption
|
|
|
|
uint32_t count;
|
|
|
|
uint32_t count;
|
|
|
|
if (sn < next_pdcp_rx_sn) {
|
|
|
|
if (sn < st.next_pdcp_rx_sn) {
|
|
|
|
count = COUNT(rx_hfn + 1, sn);
|
|
|
|
count = COUNT(st.rx_hfn + 1, sn);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
count = COUNT(rx_hfn, sn);
|
|
|
|
count = COUNT(st.rx_hfn, sn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Perform decryption
|
|
|
|
// Perform decryption
|
|
|
@ -219,14 +221,14 @@ void pdcp_entity_lte::handle_srb_pdu(srslte::unique_byte_buffer_t pdu)
|
|
|
|
discard_data_header(pdu);
|
|
|
|
discard_data_header(pdu);
|
|
|
|
|
|
|
|
|
|
|
|
// Update state variables
|
|
|
|
// Update state variables
|
|
|
|
if (sn < next_pdcp_rx_sn) {
|
|
|
|
if (sn < st.next_pdcp_rx_sn) {
|
|
|
|
rx_hfn++;
|
|
|
|
st.rx_hfn++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
next_pdcp_rx_sn = sn + 1;
|
|
|
|
st.next_pdcp_rx_sn = sn + 1;
|
|
|
|
|
|
|
|
|
|
|
|
if (next_pdcp_rx_sn > maximum_pdcp_sn) {
|
|
|
|
if (st.next_pdcp_rx_sn > maximum_pdcp_sn) {
|
|
|
|
next_pdcp_rx_sn = 0;
|
|
|
|
st.next_pdcp_rx_sn = 0;
|
|
|
|
rx_hfn++;
|
|
|
|
st.rx_hfn++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Pass to upper layers
|
|
|
|
// Pass to upper layers
|
|
|
@ -240,20 +242,20 @@ void pdcp_entity_lte::handle_um_drb_pdu(srslte::unique_byte_buffer_t pdu)
|
|
|
|
uint32_t sn = read_data_header(pdu);
|
|
|
|
uint32_t sn = read_data_header(pdu);
|
|
|
|
discard_data_header(pdu);
|
|
|
|
discard_data_header(pdu);
|
|
|
|
|
|
|
|
|
|
|
|
if (sn < next_pdcp_rx_sn) {
|
|
|
|
if (sn < st.next_pdcp_rx_sn) {
|
|
|
|
rx_hfn++;
|
|
|
|
st.rx_hfn++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t count = (rx_hfn << cfg.sn_len) | sn;
|
|
|
|
uint32_t count = (st.rx_hfn << cfg.sn_len) | sn;
|
|
|
|
if (encryption_direction == DIRECTION_RX || encryption_direction == DIRECTION_TXRX) {
|
|
|
|
if (encryption_direction == DIRECTION_RX || encryption_direction == DIRECTION_TXRX) {
|
|
|
|
cipher_decrypt(pdu->msg, pdu->N_bytes, count, pdu->msg);
|
|
|
|
cipher_decrypt(pdu->msg, pdu->N_bytes, count, pdu->msg);
|
|
|
|
log->debug_hex(pdu->msg, pdu->N_bytes, "%s Rx PDU (decrypted)", rrc->get_rb_name(lcid).c_str());
|
|
|
|
log->debug_hex(pdu->msg, pdu->N_bytes, "%s Rx PDU (decrypted)", rrc->get_rb_name(lcid).c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
next_pdcp_rx_sn = sn + 1;
|
|
|
|
st.next_pdcp_rx_sn = sn + 1;
|
|
|
|
if (next_pdcp_rx_sn > maximum_pdcp_sn) {
|
|
|
|
if (st.next_pdcp_rx_sn > maximum_pdcp_sn) {
|
|
|
|
next_pdcp_rx_sn = 0;
|
|
|
|
st.next_pdcp_rx_sn = 0;
|
|
|
|
rx_hfn++;
|
|
|
|
st.rx_hfn++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Pass to upper layers
|
|
|
|
// Pass to upper layers
|
|
|
@ -267,15 +269,15 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu)
|
|
|
|
uint32_t sn = read_data_header(pdu);
|
|
|
|
uint32_t sn = read_data_header(pdu);
|
|
|
|
discard_data_header(pdu);
|
|
|
|
discard_data_header(pdu);
|
|
|
|
|
|
|
|
|
|
|
|
int32_t last_submit_diff_sn = last_submitted_pdcp_rx_sn - sn;
|
|
|
|
int32_t last_submit_diff_sn = st.last_submitted_pdcp_rx_sn - sn;
|
|
|
|
int32_t sn_diff_last_submit = sn - last_submitted_pdcp_rx_sn;
|
|
|
|
int32_t sn_diff_last_submit = sn - st.last_submitted_pdcp_rx_sn;
|
|
|
|
int32_t sn_diff_next_pdcp_rx_sn = sn - next_pdcp_rx_sn;
|
|
|
|
int32_t sn_diff_next_pdcp_rx_sn = sn - st.next_pdcp_rx_sn;
|
|
|
|
|
|
|
|
|
|
|
|
log->debug("RX HFN: %d, SN=%d, Last_Submitted_PDCP_RX_SN=%d, Next_PDCP_RX_SN=%d\n",
|
|
|
|
log->debug("RX HFN: %d, SN=%d, Last_Submitted_PDCP_RX_SN=%d, Next_PDCP_RX_SN=%d\n",
|
|
|
|
rx_hfn,
|
|
|
|
st.rx_hfn,
|
|
|
|
sn,
|
|
|
|
sn,
|
|
|
|
last_submitted_pdcp_rx_sn,
|
|
|
|
st.last_submitted_pdcp_rx_sn,
|
|
|
|
next_pdcp_rx_sn);
|
|
|
|
st.next_pdcp_rx_sn);
|
|
|
|
|
|
|
|
|
|
|
|
// Handle PDU
|
|
|
|
// Handle PDU
|
|
|
|
uint32_t count = 0;
|
|
|
|
uint32_t count = 0;
|
|
|
@ -288,25 +290,25 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu)
|
|
|
|
last_submit_diff_sn,
|
|
|
|
last_submit_diff_sn,
|
|
|
|
reordering_window);
|
|
|
|
reordering_window);
|
|
|
|
return; // Discard
|
|
|
|
return; // Discard
|
|
|
|
} else if ((int32_t)(next_pdcp_rx_sn - sn) > (int32_t)reordering_window) {
|
|
|
|
} else if ((int32_t)(st.next_pdcp_rx_sn - sn) > (int32_t)reordering_window) {
|
|
|
|
log->debug("(Next_PDCP_RX_SN - SN) is larger than re-ordering window.\n");
|
|
|
|
log->debug("(Next_PDCP_RX_SN - SN) is larger than re-ordering window.\n");
|
|
|
|
rx_hfn++;
|
|
|
|
st.rx_hfn++;
|
|
|
|
count = (rx_hfn << cfg.sn_len) | sn;
|
|
|
|
count = (st.rx_hfn << cfg.sn_len) | sn;
|
|
|
|
next_pdcp_rx_sn = sn + 1;
|
|
|
|
st.next_pdcp_rx_sn = sn + 1;
|
|
|
|
} else if (sn_diff_next_pdcp_rx_sn >= (int32_t)reordering_window) {
|
|
|
|
} else if (sn_diff_next_pdcp_rx_sn >= (int32_t)reordering_window) {
|
|
|
|
log->debug("(SN - Next_PDCP_RX_SN) is larger or equal than re-ordering window.\n");
|
|
|
|
log->debug("(SN - Next_PDCP_RX_SN) is larger or equal than re-ordering window.\n");
|
|
|
|
count = ((rx_hfn - 1) << cfg.sn_len) | sn;
|
|
|
|
count = ((st.rx_hfn - 1) << cfg.sn_len) | sn;
|
|
|
|
} else if (sn >= next_pdcp_rx_sn) {
|
|
|
|
} else if (sn >= st.next_pdcp_rx_sn) {
|
|
|
|
log->debug("SN is larger or equal than Next_PDCP_RX_SN.\n");
|
|
|
|
log->debug("SN is larger or equal than Next_PDCP_RX_SN.\n");
|
|
|
|
count = (rx_hfn << cfg.sn_len) | sn;
|
|
|
|
count = (st.rx_hfn << cfg.sn_len) | sn;
|
|
|
|
next_pdcp_rx_sn = sn + 1;
|
|
|
|
st.next_pdcp_rx_sn = sn + 1;
|
|
|
|
if (next_pdcp_rx_sn > maximum_pdcp_sn) {
|
|
|
|
if (st.next_pdcp_rx_sn > maximum_pdcp_sn) {
|
|
|
|
next_pdcp_rx_sn = 0;
|
|
|
|
st.next_pdcp_rx_sn = 0;
|
|
|
|
rx_hfn++;
|
|
|
|
st.rx_hfn++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (sn < next_pdcp_rx_sn) {
|
|
|
|
} else if (sn < st.next_pdcp_rx_sn) {
|
|
|
|
log->debug("SN is smaller than Next_PDCP_RX_SN.\n");
|
|
|
|
log->debug("SN is smaller than Next_PDCP_RX_SN.\n");
|
|
|
|
count = (rx_hfn << cfg.sn_len) | sn;
|
|
|
|
count = (st.rx_hfn << cfg.sn_len) | sn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Decrypt
|
|
|
|
// Decrypt
|
|
|
@ -314,7 +316,7 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu)
|
|
|
|
log->debug_hex(pdu->msg, pdu->N_bytes, "%s Rx PDU (decrypted)", rrc->get_rb_name(lcid).c_str());
|
|
|
|
log->debug_hex(pdu->msg, pdu->N_bytes, "%s Rx PDU (decrypted)", rrc->get_rb_name(lcid).c_str());
|
|
|
|
|
|
|
|
|
|
|
|
// Update info on last PDU submitted to upper layers
|
|
|
|
// Update info on last PDU submitted to upper layers
|
|
|
|
last_submitted_pdcp_rx_sn = sn;
|
|
|
|
st.last_submitted_pdcp_rx_sn = sn;
|
|
|
|
|
|
|
|
|
|
|
|
// Pass to upper layers
|
|
|
|
// Pass to upper layers
|
|
|
|
log->info_hex(pdu->msg, pdu->N_bytes, "%s Rx PDU SN=%d", rrc->get_rb_name(lcid).c_str(), sn);
|
|
|
|
log->info_hex(pdu->msg, pdu->N_bytes, "%s Rx PDU SN=%d", rrc->get_rb_name(lcid).c_str(), sn);
|
|
|
@ -328,18 +330,18 @@ void pdcp_entity_lte::get_bearer_status(uint16_t* dlsn, uint16_t* dlhfn, uint16_
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (cfg.rb_type == PDCP_RB_IS_DRB) {
|
|
|
|
if (cfg.rb_type == PDCP_RB_IS_DRB) {
|
|
|
|
if (12 == cfg.sn_len) {
|
|
|
|
if (12 == cfg.sn_len) {
|
|
|
|
*dlsn = (uint16_t)(tx_count & 0xFFFu);
|
|
|
|
*dlsn = (uint16_t)(st.tx_count & 0xFFFu);
|
|
|
|
*dlhfn = (uint16_t)((tx_count - *dlsn) >> 12u);
|
|
|
|
*dlhfn = (uint16_t)((st.tx_count - *dlsn) >> 12u);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
*dlsn = (uint16_t)(tx_count & 0x7Fu);
|
|
|
|
*dlsn = (uint16_t)(st.tx_count & 0x7Fu);
|
|
|
|
*dlhfn = (uint16_t)((tx_count - *dlsn) >> 7u);
|
|
|
|
*dlhfn = (uint16_t)((st.tx_count - *dlsn) >> 7u);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else { // is control
|
|
|
|
} else { // is control
|
|
|
|
*dlsn = (uint16_t)(tx_count & 0x1Fu);
|
|
|
|
*dlsn = (uint16_t)(st.tx_count & 0x1Fu);
|
|
|
|
*dlhfn = (uint16_t)((tx_count - *dlsn) >> 5u);
|
|
|
|
*dlhfn = (uint16_t)((st.tx_count - *dlsn) >> 5u);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*ulsn = (uint16_t)next_pdcp_rx_sn;
|
|
|
|
*ulsn = (uint16_t)st.next_pdcp_rx_sn;
|
|
|
|
*ulhfn = (uint16_t)rx_hfn;
|
|
|
|
*ulhfn = (uint16_t)st.rx_hfn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
/****************************************************************************
|
|
|
@ -371,15 +373,12 @@ bool pdcp_entity_lte::check_valid_config()
|
|
|
|
***************************************************************************/
|
|
|
|
***************************************************************************/
|
|
|
|
void pdcp_entity_lte::get_state(pdcp_lte_state_t* state)
|
|
|
|
void pdcp_entity_lte::get_state(pdcp_lte_state_t* state)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
*state = {tx_count, rx_hfn, next_pdcp_rx_sn, last_submitted_pdcp_rx_sn};
|
|
|
|
*state = st;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pdcp_entity_lte::set_state(const pdcp_lte_state_t& state)
|
|
|
|
void pdcp_entity_lte::set_state(const pdcp_lte_state_t& state)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tx_count = state.tx_count;
|
|
|
|
st = state;
|
|
|
|
rx_hfn = state.rx_hfn;
|
|
|
|
|
|
|
|
next_pdcp_rx_sn = state.next_pdcp_rx_sn;
|
|
|
|
|
|
|
|
last_submitted_pdcp_rx_sn = state.last_submitted_pdcp_rx_sn;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace srslte
|
|
|
|
} // namespace srslte
|
|
|
|