Merge branch 'next' into agpl_next

This commit is contained in:
Codebot 2022-06-05 21:12:59 +00:00 committed by SRS codebot
commit 6a3b9257e3
8 changed files with 245 additions and 149 deletions

View File

@ -61,12 +61,6 @@ public:
void notify_delivery(const pdcp_sn_vector_t& pdcp_sns) final;
void notify_failure(const pdcp_sn_vector_t& pdcp_sns) final;
// State variable setters (should be used only for testing)
void set_tx_next(uint32_t tx_next_) { tx_next = tx_next_; }
void set_rx_next(uint32_t rx_next_) { rx_next = rx_next_; }
void set_rx_deliv(uint32_t rx_deliv_) { rx_deliv = rx_deliv_; }
void set_rx_reord(uint32_t rx_reord_) { rx_reord = rx_reord_; }
void get_bearer_state(pdcp_lte_state_t* state) override;
void set_bearer_state(const pdcp_lte_state_t& state, bool set_fmc) override;
@ -78,6 +72,17 @@ public:
// State variable getters (useful for testing)
uint32_t nof_discard_timers() { return discard_timers_map.size(); }
bool is_reordering_timer_running() { return reordering_timer.is_running(); }
// State variable setters (should be used only for testing)
void set_tx_next(uint32_t tx_next_) { tx_next = tx_next_; }
void set_rx_next(uint32_t rx_next_) { rx_next = rx_next_; }
void set_rx_deliv(uint32_t rx_deliv_) { rx_deliv = rx_deliv_; }
void set_rx_reord(uint32_t rx_reord_) { rx_reord = rx_reord_; }
uint32_t get_tx_next() const { return tx_next; }
uint32_t get_rx_next() const { return rx_next; }
uint32_t get_rx_deliv() const { return rx_deliv; }
uint32_t get_rx_reord() const { return rx_reord; }
private:
srsue::rlc_interface_pdcp* rlc = nullptr;

View File

@ -111,6 +111,11 @@ void pdcp_entity_nr::write_sdu(unique_byte_buffer_t sdu, int sn)
srsran_direction_text[integrity_direction],
srsran_direction_text[encryption_direction]);
if (rlc->sdu_queue_is_full(lcid)) {
logger.info(sdu->msg, sdu->N_bytes, "Dropping %s SDU due to full queue", rb_name.c_str());
return;
}
// Check for COUNT overflow
if (tx_overflow) {
logger.warning("TX_NEXT has overflowed. Dropping packet");
@ -203,7 +208,17 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
// Extract RCVD_SN from header
uint32_t rcvd_sn = read_data_header(pdu);
// Calculate RCVD_COUNT
/*
* Calculate RCVD_COUNT:
*
* - if RCVD_SN < SN(RX_DELIV) Window_Size:
* - RCVD_HFN = HFN(RX_DELIV) + 1.
* - else if RCVD_SN >= SN(RX_DELIV) + Window_Size:
* - RCVD_HFN = HFN(RX_DELIV) 1.
* - else:
* - RCVD_HFN = HFN(RX_DELIV);
* - RCVD_COUNT = [RCVD_HFN, RCVD_SN].
*/
uint32_t rcvd_hfn, rcvd_count;
if ((int64_t)rcvd_sn < (int64_t)SN(rx_deliv) - (int64_t)window_size) {
rcvd_hfn = HFN(rx_deliv) + 1;
@ -216,24 +231,33 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
logger.debug("Estimated RCVD_HFN=%u, RCVD_SN=%u, RCVD_COUNT=%u", rcvd_hfn, rcvd_sn, rcvd_count);
// TS 38.323, section 5.8: Deciphering
// The data unit that is ciphered is the MAC-I and the
// data part of the PDCP Data PDU except the
// SDAP header and the SDAP Control PDU if included in the PDCP SDU.
/*
* TS 38.323, section 5.8: Deciphering
*
* The data unit that is ciphered is the MAC-I and the
* data part of the PDCP Data PDU except the
* SDAP header and the SDAP Control PDU if included in the PDCP SDU.
*/
if (encryption_direction == DIRECTION_RX || encryption_direction == DIRECTION_TXRX) {
cipher_decrypt(
&pdu->msg[cfg.hdr_len_bytes], pdu->N_bytes - cfg.hdr_len_bytes, rcvd_count, &pdu->msg[cfg.hdr_len_bytes]);
}
// Extract MAC-I
// Always extract from SRBs, only extract from DRBs if integrity is enabled
/*
* Extract MAC-I:
* Always extract from SRBs, only extract from DRBs if integrity is enabled
*/
uint8_t mac[4] = {};
if (is_srb() || (is_drb() && (integrity_direction == DIRECTION_TX || integrity_direction == DIRECTION_TXRX))) {
extract_mac(pdu, mac);
}
// TS 38.323, section 5.9: Integrity verification
// The data unit that is integrity protected is the PDU header
// and the data part of the PDU before ciphering.
/*
* TS 38.323, section 5.9: Integrity verification
*
* The data unit that is integrity protected is the PDU header
* and the data part of the PDU before ciphering.
*/
if (integrity_direction == DIRECTION_TX || integrity_direction == DIRECTION_TXRX) {
bool is_valid = integrity_verify(pdu->msg, pdu->N_bytes, rcvd_count, mac);
if (!is_valid) {
@ -248,7 +272,13 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
// After checking the integrity, we can discard the header.
discard_data_header(pdu);
// Check valid rcvd_count
/*
* Check valid rcvd_count:
*
* - if RCVD_COUNT < RX_DELIV; or
* - if the PDCP Data PDU with COUNT = RCVD_COUNT has been received before:
* - discard the PDCP Data PDU;
*/
if (rcvd_count < rx_deliv) {
logger.debug("Out-of-order after time-out, duplicate or COUNT wrap-around");
logger.debug("RCVD_COUNT %u, RCVD_COUNT %u", rcvd_count, rx_deliv);
@ -257,6 +287,7 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
// Check if PDU has been received
if (reorder_queue.find(rcvd_count) != reorder_queue.end()) {
logger.debug("Duplicate PDU, dropping");
return; // PDU already present, drop.
}
@ -278,12 +309,14 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
// Handle reordering timers
if (reordering_timer.is_running() and rx_deliv >= rx_reord) {
reordering_timer.stop();
logger.debug("Stopped t-Reordering - RX_DELIV=%d, RX_REORD=%ld", rx_deliv, rx_reord);
}
if (cfg.t_reordering != pdcp_t_reordering_t::infinity) {
if (not reordering_timer.is_running() and rx_deliv < rx_next) {
rx_reord = rx_next;
reordering_timer.run();
logger.debug("Started t-Reordering - RX_REORD=%ld, RX_DELIV=%ld, RX_NEXT=%ld", rx_reord, rx_deliv, rx_next);
}
}
@ -294,6 +327,11 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
void pdcp_entity_nr::notify_delivery(const pdcp_sn_vector_t& pdcp_sns)
{
logger.debug("Received delivery notification from RLC. Nof SNs=%ld", pdcp_sns.size());
for (uint32_t sn : pdcp_sns) {
// Remove timer from map
logger.debug("Stopping discard timer for SN=%ld", sn);
discard_timers_map.erase(sn);
}
}
void pdcp_entity_nr::notify_failure(const pdcp_sn_vector_t& pdcp_sns)
@ -337,7 +375,8 @@ void pdcp_entity_nr::deliver_all_consecutive_counts()
// Reordering Timer Callback (t-reordering)
void pdcp_entity_nr::reordering_callback::operator()(uint32_t timer_id)
{
parent->logger.info("Reordering timer expired. Re-order queue size=%d", parent->reorder_queue.size());
parent->logger.info(
"Reordering timer expired. RX_REORD=%u, re-order queue size=%ld", parent->rx_reord, parent->reorder_queue.size());
// Deliver all PDCP SDU(s) with associated COUNT value(s) < RX_REORD
for (std::map<uint32_t, unique_byte_buffer_t>::iterator it = parent->reorder_queue.begin();
@ -347,10 +386,17 @@ void pdcp_entity_nr::reordering_callback::operator()(uint32_t timer_id)
parent->pass_to_upper_layers(std::move(it->second));
}
// Update RX_DELIV to the first PDCP SDU not delivered to the upper layers
parent->rx_deliv = parent->rx_reord;
// Deliver all PDCP SDU(s) consecutively associated COUNT value(s) starting from RX_REORD
parent->deliver_all_consecutive_counts();
if (parent->rx_deliv < parent->rx_next) {
parent->logger.debug("Updating RX_REORD to %ld. Old RX_REORD=%ld, RX_DELIV=%ld",
parent->rx_next,
parent->rx_reord,
parent->rx_deliv);
parent->rx_reord = parent->rx_next;
parent->reordering_timer.run();
}
@ -359,7 +405,7 @@ void pdcp_entity_nr::reordering_callback::operator()(uint32_t timer_id)
// Discard Timer Callback (discardTimer)
void pdcp_entity_nr::discard_callback::operator()(uint32_t timer_id)
{
parent->logger.debug("Discard timer expired for PDU with SN = %d", discard_sn);
parent->logger.debug("Discard timer expired for PDU with SN=%d", discard_sn);
// Notify the RLC of the discard. It's the RLC to actually discard, if no segment was transmitted yet.
parent->rlc->discard_sdu(parent->lcid, discard_sn);

View File

@ -248,13 +248,19 @@ int rlc_am::rlc_am_base_tx::write_sdu(unique_byte_buffer_t sdu)
uint32_t nof_bytes = sdu->N_bytes;
srsran::error_type<unique_byte_buffer_t> ret = tx_sdu_queue.try_write(std::move(sdu));
if (ret) {
RlcHexInfo(msg_ptr, nof_bytes, "Tx SDU (%d B, tx_sdu_queue_len=%d)", nof_bytes, tx_sdu_queue.size());
RlcHexInfo(msg_ptr,
nof_bytes,
"Tx SDU (%d B, PDCP_SN=%ld tx_sdu_queue_len=%d)",
nof_bytes,
sdu_pdcp_sn,
tx_sdu_queue.size());
} else {
// in case of fail, the try_write returns back the sdu
RlcHexWarning(ret.error()->msg,
ret.error()->N_bytes,
"[Dropped SDU] Tx SDU (%d B, tx_sdu_queue_len=%d)",
"[Dropped SDU] Tx SDU (%d B, PDCP_SN=%ld, tx_sdu_queue_len=%d)",
ret.error()->N_bytes,
sdu_pdcp_sn,
tx_sdu_queue.size());
return SRSRAN_ERROR;
}
@ -273,6 +279,7 @@ void rlc_am::rlc_am_base_tx::discard_sdu(uint32_t discard_sn)
if (sdu != nullptr && sdu->md.pdcp_sn == discard_sn) {
tx_sdu_queue.queue.pop_func(sdu);
sdu = nullptr;
return true;
}
return false;
});

View File

@ -192,7 +192,7 @@ uint32_t rlc_am_nr_tx::build_new_pdu(uint8_t* payload, uint32_t nof_bytes)
} while (tx_sdu == nullptr && tx_sdu_queue.size() != 0);
if (tx_sdu != nullptr) {
RlcDebug("Read RLC SDU - %d bytes", tx_sdu->N_bytes);
RlcDebug("Read RLC SDU - RLC_SN=%d, PDCP_SN=%d, %d bytes", st.tx_next, tx_sdu->md.pdcp_sn, tx_sdu->N_bytes);
} else {
RlcDebug("No SDUs left in the tx queue.");
return 0;

View File

@ -22,48 +22,60 @@
#include <numeric>
/*
* Genric function to test reception of in-sequence packets
* Generic class to test reception of in-sequence packets
*/
int test_rx(std::vector<pdcp_test_event_t> events,
const pdcp_initial_state& init_state,
uint8_t pdcp_sn_len,
uint32_t n_sdus_exp,
const srsran::unique_byte_buffer_t& sdu_exp,
srslog::basic_logger& logger)
class test_rx_helper
{
srsran::pdcp_config_t cfg_rx = {1,
srsran::PDCP_RB_IS_DRB,
srsran::SECURITY_DIRECTION_DOWNLINK,
srsran::SECURITY_DIRECTION_UPLINK,
pdcp_sn_len,
srsran::pdcp_t_reordering_t::ms500,
srsran::pdcp_discard_timer_t::infinity,
false,
srsran::srsran_rat_t::nr};
public:
pdcp_nr_test_helper pdcp_hlp_rx;
srsran::pdcp_entity_nr& pdcp_rx;
gw_dummy& gw_rx;
srsue::stack_test_dummy& stack;
srslog::basic_logger& logger;
pdcp_nr_test_helper pdcp_hlp_rx(cfg_rx, sec_cfg, logger);
srsran::pdcp_entity_nr* pdcp_rx = &pdcp_hlp_rx.pdcp;
gw_dummy* gw_rx = &pdcp_hlp_rx.gw;
srsue::stack_test_dummy* stack = &pdcp_hlp_rx.stack;
pdcp_hlp_rx.set_pdcp_initial_state(init_state);
test_rx_helper(uint8_t pdcp_sn_len, srslog::basic_logger& logger) :
pdcp_hlp_rx({1,
srsran::PDCP_RB_IS_DRB,
srsran::SECURITY_DIRECTION_DOWNLINK,
srsran::SECURITY_DIRECTION_UPLINK,
pdcp_sn_len,
srsran::pdcp_t_reordering_t::ms500,
srsran::pdcp_discard_timer_t::infinity,
false,
srsran::srsran_rat_t::nr},
sec_cfg,
logger),
pdcp_rx(pdcp_hlp_rx.pdcp),
gw_rx(pdcp_hlp_rx.gw),
stack(pdcp_hlp_rx.stack),
logger(logger)
{}
// Generate test message and encript/decript SDU.
for (pdcp_test_event_t& event : events) {
// Decript and integrity check the PDU
pdcp_rx->write_pdu(std::move(event.pkt));
for (uint32_t i = 0; i < event.ticks; ++i) {
stack->run_tti();
int test_rx(std::vector<pdcp_test_event_t> events,
const pdcp_initial_state& init_state,
uint32_t n_sdus_exp,
const srsran::unique_byte_buffer_t& sdu_exp)
{
pdcp_hlp_rx.set_pdcp_initial_state(init_state);
// Generate test message and encrypt/decrypt SDU.
for (pdcp_test_event_t& event : events) {
// Decrypt and integrity check the PDU
pdcp_rx.write_pdu(std::move(event.pkt));
for (uint32_t i = 0; i < event.ticks; ++i) {
stack.run_tti();
}
}
}
// Test if the number of RX packets
TESTASSERT_EQ(gw_rx->rx_count, n_sdus_exp);
srsran::unique_byte_buffer_t sdu_act = srsran::make_byte_buffer();
gw_rx->get_last_pdu(sdu_act);
TESTASSERT(compare_two_packets(sdu_exp, sdu_act) == 0);
return 0;
}
// Test if the number of RX packets
TESTASSERT_EQ(gw_rx.rx_count, n_sdus_exp);
srsran::unique_byte_buffer_t sdu_act = srsran::make_byte_buffer();
gw_rx.get_last_pdu(sdu_act);
TESTASSERT(compare_two_packets(sdu_exp, sdu_act) == 0);
return 0;
}
};
/*
* RX Test: PDCP Entity with SN LEN = 12 and 18.
@ -85,12 +97,13 @@ int test_rx_all(srslog::basic_logger& logger)
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("RX COUNT [4095,4096], 12 bit SN");
test_rx_helper rx_helper(srsran::PDCP_SN_LEN_12, logger);
std::vector<uint32_t> test1_counts(2); // Test two packets
std::iota(test1_counts.begin(), test1_counts.end(), 4095); // Starting at COUNT 4095
std::vector<pdcp_test_event_t> test1_pdus =
gen_expected_pdus_vector(tst_sdu1, test1_counts, srsran::PDCP_SN_LEN_12, sec_cfg, logger);
pdcp_initial_state test1_init_state = {.tx_next = 4095, .rx_next = 4095, .rx_deliv = 4095, .rx_reord = 0};
TESTASSERT(test_rx(std::move(test1_pdus), test1_init_state, srsran::PDCP_SN_LEN_12, 2, tst_sdu1, logger) == 0);
TESTASSERT(rx_helper.test_rx(std::move(test1_pdus), test1_init_state, 2, tst_sdu1) == 0);
}
/*
* RX Test 2: PDCP Entity with SN LEN = 12
@ -101,13 +114,14 @@ int test_rx_all(srslog::basic_logger& logger)
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("RX COUNT [4294967295,0], 12 bit SN");
test_rx_helper rx_helper(srsran::PDCP_SN_LEN_12, logger);
std::vector<uint32_t> test2_counts(2); // Test two packets
std::iota(test2_counts.begin(), test2_counts.end(), 4294967295); // Starting at COUNT 4294967295
std::vector<pdcp_test_event_t> test2_pdus =
gen_expected_pdus_vector(tst_sdu1, test2_counts, srsran::PDCP_SN_LEN_12, sec_cfg, logger);
pdcp_initial_state test2_init_state = {
.tx_next = 4294967295, .rx_next = 4294967295, .rx_deliv = 4294967295, .rx_reord = 0};
TESTASSERT(test_rx(std::move(test2_pdus), test2_init_state, srsran::PDCP_SN_LEN_12, 1, tst_sdu1, logger) == 0);
TESTASSERT(rx_helper.test_rx(std::move(test2_pdus), test2_init_state, 1, tst_sdu1) == 0);
}
/*
* RX Test 3: PDCP Entity with SN LEN = 18
@ -117,12 +131,13 @@ int test_rx_all(srslog::basic_logger& logger)
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("RX COUNT [262144,262145], 12 bit SN");
test_rx_helper rx_helper(srsran::PDCP_SN_LEN_18, logger);
std::vector<uint32_t> test3_counts(2); // Test two packets
std::iota(test3_counts.begin(), test3_counts.end(), 262144); // Starting at COUNT 262144
std::vector<pdcp_test_event_t> test3_pdus =
gen_expected_pdus_vector(tst_sdu1, test3_counts, srsran::PDCP_SN_LEN_18, sec_cfg, logger);
pdcp_initial_state test3_init_state = {.tx_next = 262144, .rx_next = 262144, .rx_deliv = 262144, .rx_reord = 0};
TESTASSERT(test_rx(std::move(test3_pdus), test3_init_state, srsran::PDCP_SN_LEN_18, 2, tst_sdu1, logger) == 0);
TESTASSERT(rx_helper.test_rx(std::move(test3_pdus), test3_init_state, 2, tst_sdu1) == 0);
}
/*
@ -133,22 +148,25 @@ int test_rx_all(srslog::basic_logger& logger)
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("RX COUNT [4294967295,4294967296], 18 bit SN");
test_rx_helper rx_helper(srsran::PDCP_SN_LEN_18, logger);
std::vector<uint32_t> test4_counts(2); // Test two packets
std::iota(test4_counts.begin(), test4_counts.end(), 4294967295); // Starting at COUNT 4294967295
std::vector<pdcp_test_event_t> test4_pdus =
gen_expected_pdus_vector(tst_sdu1, test4_counts, srsran::PDCP_SN_LEN_18, sec_cfg, logger);
pdcp_initial_state test4_init_state = {
.tx_next = 4294967295, .rx_next = 4294967295, .rx_deliv = 4294967295, .rx_reord = 0};
TESTASSERT(test_rx(std::move(test4_pdus), test4_init_state, srsran::PDCP_SN_LEN_18, 1, tst_sdu1, logger) == 0);
TESTASSERT(rx_helper.test_rx(std::move(test4_pdus), test4_init_state, 1, tst_sdu1) == 0);
}
/*
* RX Test 5: PDCP Entity with SN LEN = 12
* Test reception of two out-of-order packets, starting at COUNT 0.
* Both packets are received and delivered before t-Reordering expires.
*/
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("RX out-of-order COUNT [1,0], 12 bit SN");
test_rx_helper rx_helper(srsran::PDCP_SN_LEN_12, logger);
std::vector<pdcp_test_event_t> test5_pdus;
pdcp_initial_state test5_init_state = {};
@ -165,16 +183,21 @@ int test_rx_all(srslog::basic_logger& logger)
// Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after)
test5_pdus.push_back(std::move(event_pdu2));
test5_pdus.push_back(std::move(event_pdu1));
TESTASSERT(test_rx(std::move(test5_pdus), test5_init_state, srsran::PDCP_SN_LEN_12, 2, tst_sdu2, logger) == 0);
TESTASSERT(rx_helper.test_rx(std::move(test5_pdus), test5_init_state, 2, tst_sdu2) == 0);
TESTASSERT(rx_helper.pdcp_rx.is_reordering_timer_running() == false);
TESTASSERT(rx_helper.pdcp_rx.get_rx_deliv() == 2);
TESTASSERT(rx_helper.pdcp_rx.get_rx_reord() == 2);
}
/*
* RX Test 6: PDCP Entity with SN LEN = 18
* Test reception of two out-of-order packets, starting at COUNT 0.
* Both packets are received and delivered before t-Reordering expires.
*/
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("RX out-of-order COUNT [1,0], 18 bit SN");
test_rx_helper rx_helper(srsran::PDCP_SN_LEN_18, logger);
std::vector<pdcp_test_event_t> test6_pdus;
pdcp_initial_state test6_init_state = {};
@ -191,7 +214,10 @@ int test_rx_all(srslog::basic_logger& logger)
// Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after)
test6_pdus.push_back(std::move(event_pdu2));
test6_pdus.push_back(std::move(event_pdu1));
TESTASSERT(test_rx(std::move(test6_pdus), test6_init_state, srsran::PDCP_SN_LEN_18, 2, tst_sdu2, logger) == 0);
TESTASSERT(rx_helper.test_rx(std::move(test6_pdus), test6_init_state, 2, tst_sdu2) == 0);
TESTASSERT(rx_helper.pdcp_rx.is_reordering_timer_running() == false);
TESTASSERT(rx_helper.pdcp_rx.get_rx_deliv() == 2);
TESTASSERT(rx_helper.pdcp_rx.get_rx_reord() == 2);
}
/*
@ -201,6 +227,7 @@ int test_rx_all(srslog::basic_logger& logger)
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("RX out-of-order COUNT [1,0] t_reordering expired, 12 bit SN");
test_rx_helper rx_helper(srsran::PDCP_SN_LEN_12, logger);
std::vector<pdcp_test_event_t> test7_pdus;
pdcp_initial_state test7_init_state = {};
@ -212,7 +239,10 @@ int test_rx_all(srslog::basic_logger& logger)
// Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after)
test7_pdus.push_back(std::move(event_pdu1));
TESTASSERT(test_rx(std::move(test7_pdus), test7_init_state, srsran::PDCP_SN_LEN_12, 1, tst_sdu2, logger) == 0);
TESTASSERT(rx_helper.test_rx(std::move(test7_pdus), test7_init_state, 1, tst_sdu2) == 0);
TESTASSERT(rx_helper.pdcp_rx.is_reordering_timer_running() == false);
TESTASSERT(rx_helper.pdcp_rx.get_rx_deliv() == 2);
TESTASSERT(rx_helper.pdcp_rx.get_rx_reord() == 2);
}
/*
@ -221,6 +251,7 @@ int test_rx_all(srslog::basic_logger& logger)
*/
{
srsran::test_delimit_logger delimiter("RX duplicate COUNTs [0,0], 12 bit SN");
test_rx_helper rx_helper(srsran::PDCP_SN_LEN_12, logger);
std::vector<pdcp_test_event_t> test8_pdus;
pdcp_initial_state test8_init_state = {};
@ -237,7 +268,7 @@ int test_rx_all(srslog::basic_logger& logger)
// Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after)
test8_pdus.push_back(std::move(event_pdu1));
test8_pdus.push_back(std::move(event_pdu2));
TESTASSERT(test_rx(std::move(test8_pdus), test8_init_state, srsran::PDCP_SN_LEN_12, 1, tst_sdu1, logger) == 0);
TESTASSERT(rx_helper.test_rx(std::move(test8_pdus), test8_init_state, 1, tst_sdu1) == 0);
}
return 0;
}

View File

@ -22,46 +22,57 @@
#include <numeric>
/*
* Genric function to test transmission of in-sequence packets
* Generic class to test transmission of in-sequence packets
*/
int test_tx(uint32_t n_packets,
const pdcp_initial_state& init_state,
uint8_t pdcp_sn_len,
uint64_t n_pdus_exp,
srsran::unique_byte_buffer_t pdu_exp,
srslog::basic_logger& logger)
class test_tx_helper
{
srsran::pdcp_config_t cfg = {1,
srsran::PDCP_RB_IS_DRB,
srsran::SECURITY_DIRECTION_UPLINK,
srsran::SECURITY_DIRECTION_DOWNLINK,
pdcp_sn_len,
srsran::pdcp_t_reordering_t::ms500,
srsran::pdcp_discard_timer_t::infinity,
false,
srsran::srsran_rat_t::nr};
public:
pdcp_nr_test_helper pdcp_hlp_tx;
srsran::pdcp_entity_nr& pdcp_tx;
rlc_dummy& rlc_tx;
srsue::stack_test_dummy& stack;
srslog::basic_logger& logger;
pdcp_nr_test_helper pdcp_hlp(cfg, sec_cfg, logger);
srsran::pdcp_entity_nr* pdcp = &pdcp_hlp.pdcp;
rlc_dummy* rlc = &pdcp_hlp.rlc;
test_tx_helper(uint8_t pdcp_sn_len, srslog::basic_logger& logger) :
pdcp_hlp_tx({1,
srsran::PDCP_RB_IS_DRB,
srsran::SECURITY_DIRECTION_UPLINK,
srsran::SECURITY_DIRECTION_DOWNLINK,
pdcp_sn_len,
srsran::pdcp_t_reordering_t::ms500,
srsran::pdcp_discard_timer_t::ms500,
false,
srsran::srsran_rat_t::nr},
sec_cfg,
logger),
pdcp_tx(pdcp_hlp_tx.pdcp),
rlc_tx(pdcp_hlp_tx.rlc),
stack(pdcp_hlp_tx.stack),
logger(logger)
{}
int test_tx(uint32_t n_packets,
const pdcp_initial_state& init_state,
uint64_t n_pdus_exp,
srsran::unique_byte_buffer_t pdu_exp)
{
pdcp_hlp_tx.set_pdcp_initial_state(init_state);
pdcp_hlp.set_pdcp_initial_state(init_state);
// Run test
for (uint32_t i = 0; i < n_packets; ++i) {
// Test SDU
srsran::unique_byte_buffer_t sdu = srsran::make_byte_buffer();
sdu->append_bytes(sdu1, sizeof(sdu1));
pdcp_hlp_tx.pdcp.write_sdu(std::move(sdu));
}
// Run test
for (uint32_t i = 0; i < n_packets; ++i) {
// Test SDU
srsran::unique_byte_buffer_t sdu = srsran::make_byte_buffer();
sdu->append_bytes(sdu1, sizeof(sdu1));
pdcp->write_sdu(std::move(sdu));
srsran::unique_byte_buffer_t pdu_act = srsran::make_byte_buffer();
pdcp_hlp_tx.rlc.get_last_sdu(pdu_act);
TESTASSERT(pdcp_hlp_tx.rlc.rx_count == n_pdus_exp);
TESTASSERT(compare_two_packets(pdu_act, pdu_exp) == 0);
return 0;
}
srsran::unique_byte_buffer_t pdu_act = srsran::make_byte_buffer();
rlc->get_last_sdu(pdu_act);
TESTASSERT(rlc->rx_count == n_pdus_exp);
TESTASSERT(compare_two_packets(pdu_act, pdu_exp) == 0);
return 0;
}
};
/*
* TX Test: PDCP Entity with SN LEN = 12 and 18.
@ -79,13 +90,11 @@ int test_tx_all(srslog::basic_logger& logger)
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("TX COUNT 0, 12 bit SN");
test_tx_helper tx_helper(srsran::PDCP_SN_LEN_12, logger);
n_packets = 1;
srsran::unique_byte_buffer_t pdu_exp_count0_len12 = srsran::make_byte_buffer();
pdu_exp_count0_len12->append_bytes(pdu1_count0_snlen12, sizeof(pdu1_count0_snlen12));
TESTASSERT(
test_tx(
n_packets, normal_init_state, srsran::PDCP_SN_LEN_12, n_packets, std::move(pdu_exp_count0_len12), logger) ==
0);
TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count0_len12)) == 0);
}
/*
* TX Test 2: PDCP Entity with SN LEN = 12
@ -96,15 +105,11 @@ int test_tx_all(srslog::basic_logger& logger)
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("TX COUNT 2048, 12 bit SN");
test_tx_helper tx_helper(srsran::PDCP_SN_LEN_12, logger);
n_packets = 2049;
srsran::unique_byte_buffer_t pdu_exp_count2048_len12 = srsran::make_byte_buffer();
pdu_exp_count2048_len12->append_bytes(pdu1_count2048_snlen12, sizeof(pdu1_count2048_snlen12));
TESTASSERT(test_tx(n_packets,
normal_init_state,
srsran::PDCP_SN_LEN_12,
n_packets,
std::move(pdu_exp_count2048_len12),
logger) == 0);
TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count2048_len12)) == 0);
}
/*
* TX Test 3: PDCP Entity with SN LEN = 12
@ -115,15 +120,12 @@ int test_tx_all(srslog::basic_logger& logger)
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("TX COUNT 4096, 12 bit SN");
test_tx_helper tx_helper(srsran::PDCP_SN_LEN_12, logger);
n_packets = 2049;
n_packets = 4097;
srsran::unique_byte_buffer_t pdu_exp_count4096_len12 = srsran::make_byte_buffer();
pdu_exp_count4096_len12->append_bytes(pdu1_count4096_snlen12, sizeof(pdu1_count4096_snlen12));
TESTASSERT(test_tx(n_packets,
normal_init_state,
srsran::PDCP_SN_LEN_12,
n_packets,
std::move(pdu_exp_count4096_len12),
logger) == 0);
TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count4096_len12)) == 0);
}
/*
* TX Test 4: PDCP Entity with SN LEN = 18
@ -134,13 +136,11 @@ int test_tx_all(srslog::basic_logger& logger)
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("TX COUNT 0, 18 bit SN");
test_tx_helper tx_helper(srsran::PDCP_SN_LEN_18, logger);
n_packets = 1;
srsran::unique_byte_buffer_t pdu_exp_count0_len18 = srsran::make_byte_buffer();
pdu_exp_count0_len18->append_bytes(pdu1_count0_snlen18, sizeof(pdu1_count0_snlen18));
TESTASSERT(
test_tx(
n_packets, normal_init_state, srsran::PDCP_SN_LEN_18, n_packets, std::move(pdu_exp_count0_len18), logger) ==
0);
TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count0_len18)) == 0);
}
/*
@ -152,15 +152,11 @@ int test_tx_all(srslog::basic_logger& logger)
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("TX COUNT 131072, 18 bit SN");
test_tx_helper tx_helper(srsran::PDCP_SN_LEN_18, logger);
n_packets = 131073;
srsran::unique_byte_buffer_t pdu_exp_sn131072_len18 = srsran::make_byte_buffer();
pdu_exp_sn131072_len18->append_bytes(pdu1_count131072_snlen18, sizeof(pdu1_count131072_snlen18));
TESTASSERT(test_tx(n_packets,
normal_init_state,
srsran::PDCP_SN_LEN_18,
n_packets,
std::move(pdu_exp_sn131072_len18),
logger) == 0);
TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_sn131072_len18)) == 0);
}
/*
@ -172,15 +168,11 @@ int test_tx_all(srslog::basic_logger& logger)
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("TX COUNT 262144, 18 bit SN");
test_tx_helper tx_helper(srsran::PDCP_SN_LEN_18, logger);
n_packets = 262145;
srsran::unique_byte_buffer_t pdu_exp_count262144_len18 = srsran::make_byte_buffer();
pdu_exp_count262144_len18->append_bytes(pdu1_count262144_snlen18, sizeof(pdu1_count262144_snlen18));
TESTASSERT(test_tx(n_packets,
normal_init_state,
srsran::PDCP_SN_LEN_18,
n_packets,
std::move(pdu_exp_count262144_len18),
logger) == 0);
TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count262144_len18)) == 0);
}
/*
* TX Test 7: PDCP Entity with SN LEN = 12
@ -189,16 +181,13 @@ int test_tx_all(srslog::basic_logger& logger)
*/
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("TX COUNT wrap arround, 12 bit SN");
srsran::test_delimit_logger delimiter("TX COUNT wrap around, 12 bit SN");
test_tx_helper tx_helper(srsran::PDCP_SN_LEN_12, logger);
n_packets = 5;
srsran::unique_byte_buffer_t pdu_exp_count4294967295_len12 = srsran::make_byte_buffer();
pdu_exp_count4294967295_len12->append_bytes(pdu1_count4294967295_snlen12, sizeof(pdu1_count4294967295_snlen12));
TESTASSERT(test_tx(n_packets,
near_wraparound_init_state,
srsran::PDCP_SN_LEN_12,
1,
std::move(pdu_exp_count4294967295_len12),
logger) == 0);
TESTASSERT(tx_helper.test_tx(n_packets, near_wraparound_init_state, 1, std::move(pdu_exp_count4294967295_len12)) ==
0);
}
/*
@ -208,16 +197,30 @@ int test_tx_all(srslog::basic_logger& logger)
*/
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("TX COUNT wrap arround, 12 bit SN");
srsran::test_delimit_logger delimiter("TX COUNT wrap around, 12 bit SN");
test_tx_helper tx_helper(srsran::PDCP_SN_LEN_18, logger);
n_packets = 5;
srsran::unique_byte_buffer_t pdu_exp_count4294967295_len18 = srsran::make_byte_buffer();
pdu_exp_count4294967295_len18->append_bytes(pdu1_count4294967295_snlen18, sizeof(pdu1_count4294967295_snlen18));
TESTASSERT(test_tx(n_packets,
near_wraparound_init_state,
srsran::PDCP_SN_LEN_18,
1,
std::move(pdu_exp_count4294967295_len18),
logger) == 0);
TESTASSERT(tx_helper.test_tx(n_packets, near_wraparound_init_state, 1, std::move(pdu_exp_count4294967295_len18)) ==
0);
}
/*
* TX Test 9: PDCP Entity with SN LEN = 12
* Test whether discard timers are correctly stopped after receiving a notification from the RLC
*/
{
auto& test_logger = srslog::fetch_basic_logger("TESTER ");
srsran::test_delimit_logger delimiter("Stop discard timers upon RLC notification, 12 bit SN");
test_tx_helper tx_helper(srsran::PDCP_SN_LEN_12, logger);
n_packets = 1;
srsran::unique_byte_buffer_t pdu_exp_count0_len12 = srsran::make_byte_buffer();
pdu_exp_count0_len12->append_bytes(pdu1_count0_snlen12, sizeof(pdu1_count0_snlen12));
TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count0_len12)) == 0);
TESTASSERT(tx_helper.pdcp_tx.nof_discard_timers() == 1);
tx_helper.pdcp_tx.notify_delivery({0});
TESTASSERT(tx_helper.pdcp_tx.nof_discard_timers() == 0);
}
return SRSRAN_SUCCESS;
}

View File

@ -228,8 +228,9 @@ void run_ng_initial_ue(ngap& ngap_obj, amf_dummy& amf, rrc_nr_dummy& rrc)
container->ran_ue_ngap_id.value = 0x1;
container->nas_pdu_present = true;
// Set allowed NSSAI (FIXME)
// Set allowed NSSAI
container->allowed_nssai.value.resize(1);
container->allowed_nssai.value[0].s_nssai.sst.from_number(1);
// Set security key
uint8_t sec_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,

View File

@ -20,7 +20,7 @@
*/
#include "srsue/hdr/stack/upper/nas_5g_procedures.h"
#include "srsran/common/standard_streams.h"
#include <fstream>
#include <iomanip>
#include <iostream>
@ -86,7 +86,10 @@ srsran::proc_outcome_t nas_5g::pdu_session_establishment_procedure::react(
srsran::proc_outcome_t nas_5g::pdu_session_establishment_procedure::react(
const srsran::nas_5g::pdu_session_establishment_reject_t& session_est_reject)
{
logger.info("PDU Session Establishment Reject with cause: %s", session_est_reject.cause_5gsm.cause_value.to_string());
logger.error("PDU Session Establishment Reject with cause: %s",
session_est_reject.cause_5gsm.cause_value.to_string());
srsran::console("PDU Session Establishment Reject with cause: %s\n",
session_est_reject.cause_5gsm.cause_value.to_string());
return srsran::proc_outcome_t::error;
}