Starting to move pdcp configs to rrc_interface_types. Starting to add test for reorder timeout.

This commit is contained in:
Pedro Alvarez 2019-10-02 16:55:40 +01:00 committed by Andre Puschmann
parent 6cf2bd7bc3
commit 45d298507b
5 changed files with 118 additions and 55 deletions

View File

@ -67,40 +67,6 @@ public:
uint32_t lcid;
};
const uint8_t PDCP_SN_LEN_5 = 5;
const uint8_t PDCP_SN_LEN_7 = 7;
const uint8_t PDCP_SN_LEN_12 = 12;
const uint8_t PDCP_SN_LEN_18 = 18;
typedef enum { PDCP_RB_IS_SRB, PDCP_RB_IS_DRB } pdcp_rb_type_t;
class pdcp_config_t
{
public:
pdcp_config_t(uint8_t bearer_id_,
pdcp_rb_type_t rb_type_,
security_direction_t tx_direction_,
security_direction_t rx_direction_,
uint8_t sn_len_) :
bearer_id(bearer_id_),
rb_type(rb_type_),
tx_direction(tx_direction_),
rx_direction(rx_direction_),
sn_len(sn_len_)
{
hdr_len_bytes = ceil((float)sn_len / 8);
}
uint8_t bearer_id = 1;
pdcp_rb_type_t rb_type = PDCP_RB_IS_DRB;
security_direction_t tx_direction = SECURITY_DIRECTION_DOWNLINK;
security_direction_t rx_direction = SECURITY_DIRECTION_UPLINK;
uint8_t sn_len = PDCP_SN_LEN_12;
uint8_t hdr_len_bytes = 2;
// TODO: Support the following configurations
// bool do_rohc;
};
class read_pdu_interface
{

View File

@ -354,6 +354,51 @@ public:
}
};
/***************************
* PDCP Config
**************************/
// LTE and NR common config
const uint8_t PDCP_SN_LEN_5 = 5;
const uint8_t PDCP_SN_LEN_7 = 7;
const uint8_t PDCP_SN_LEN_12 = 12;
const uint8_t PDCP_SN_LEN_18 = 18;
typedef enum { PDCP_RB_IS_SRB, PDCP_RB_IS_DRB } pdcp_rb_type_t;
enum class pdcp_t_reordering_t { ms0 = 0, ms1 = 1 , am, nulltype };
class pdcp_config_t
{
public:
pdcp_config_t(uint8_t bearer_id_,
pdcp_rb_type_t rb_type_,
security_direction_t tx_direction_,
security_direction_t rx_direction_,
uint8_t sn_len_) :
bearer_id(bearer_id_),
rb_type(rb_type_),
tx_direction(tx_direction_),
rx_direction(rx_direction_),
sn_len(sn_len_)
{
hdr_len_bytes = ceil((float)sn_len / 8);
}
uint8_t bearer_id = 1;
pdcp_rb_type_t rb_type = PDCP_RB_IS_DRB;
security_direction_t tx_direction = SECURITY_DIRECTION_DOWNLINK;
security_direction_t rx_direction = SECURITY_DIRECTION_UPLINK;
uint8_t sn_len = PDCP_SN_LEN_12;
uint8_t hdr_len_bytes = 2;
// TODO: Support the following configurations
// bool do_rohc;
};
// LTE specific config
// NR specific config
/***************************
* MAC Config
**************************/

View File

@ -66,9 +66,6 @@ private:
srsue::rrc_interface_pdcp* rrc = nullptr;
srsue::gw_interface_pdcp* gw = nullptr;
// Reordering Queue
std::map<uint32_t, unique_byte_buffer_t> reorder_queue;
// State variables: 3GPP TS 38.323 v15.2.0, section 7.1
uint32_t tx_next = 0; // COUNT value of next SDU to be transmitted.
uint32_t rx_next = 0; // COUNT value of next SDU expected to be received.
@ -78,6 +75,11 @@ private:
// Constants: 3GPP TS 38.323 v15.2.0, section 7.2
uint32_t window_size = 0;
// Reordering Queue / Timers
std::map<uint32_t, unique_byte_buffer_t> reorder_queue;
srslte::timers::timer* reordering_timer = nullptr;
uint32_t reordering_timer_id = 0;
// Packing/Unpacking Helper functions
uint32_t read_data_header(const unique_byte_buffer_t& sdu);
void write_data_header(const unique_byte_buffer_t& sdu, uint32_t sn);

View File

@ -49,6 +49,11 @@ void pdcp_entity_nr::init(srsue::rlc_interface_pdcp* rlc_,
do_encryption = false;
window_size = 1 << (cfg.sn_len - 1);
// Timers
reordering_timer_id = timers->get_unique_id();
reordering_timer = timers->get(reordering_timer_id);
}
// Reestablishment procedure: 38.323 5.2
@ -135,6 +140,8 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
}
rcvd_count = COUNT(rcvd_hfn, rcvd_sn);
log->debug("RCVD_SN %d, RCVD_COUNT %d\n", rcvd_sn, rcvd_count);
// Decripting
cipher_decrypt(pdu->msg, pdu->N_bytes, rcvd_count, pdu->msg);
@ -166,25 +173,23 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
if (rcvd_count == rx_deliv) {
// Deliver to upper layers in ascending order of associeted COUNT
log->debug("Delivering SDU(s) to upper layers\n");
for (std::map<uint32_t, unique_byte_buffer_t>::iterator it = reorder_queue.begin();
it != reorder_queue.end();) {
if (it->first == rx_deliv) {
// Pass to upper layers
if (is_srb()) {
rrc->write_pdu(lcid, std::move(it->second));
} else {
gw->write_pdu(lcid, std::move(it->second));
}
it != reorder_queue.end() && it->first == rx_deliv;) {
log->debug("Delivering SDU with RCVD_COUNT %d\n", it->first);
// Remove from queue
reorder_queue.erase(it++);
// Update RX_DELIV
rx_deliv = rx_deliv + 1; // TODO needs to be corrected when queueing is implemented
printf("New RX_deliv %d, rcvd_count %d\n", rx_deliv, rcvd_count);
// Pass to upper layers
if (is_srb()) {
rrc->write_pdu(lcid, std::move(it->second));
} else {
break;
gw->write_pdu(lcid, std::move(it->second));
}
// Remove from queue
reorder_queue.erase(it++);
// Update RX_DELIV
rx_deliv = rx_deliv + 1; // TODO needs to be corrected when queueing is implemented
}
}

View File

@ -373,6 +373,50 @@ int test_rx_out_of_order(uint8_t pdcp_sn_len, srslte::byte_buffer_pool* pool, sr
return 0;
}
/*
* RX Test: PDCP Entity with packtes received out of order
* PDCP entity configured with EIA2 and EEA2
*/
int test_rx_out_of_order_timeout(uint8_t pdcp_sn_len, srslte::byte_buffer_pool* pool, srslte::log* log)
{
srslte::pdcp_entity_nr pdcp_rx;
srslte::pdcp_config_t cfg_rx = {
1, srslte::PDCP_RB_IS_DRB, srslte::SECURITY_DIRECTION_DOWNLINK, srslte::SECURITY_DIRECTION_UPLINK, pdcp_sn_len};
rlc_dummy rlc_rx(log);
rrc_dummy rrc_rx(log);
gw_dummy gw_rx(log);
srslte::timers timers_rx(64);
pdcp_rx.init(&rlc_rx, &rrc_rx, &gw_rx, &timers_rx, log, 0, cfg_rx);
pdcp_rx.config_security(
k_enc, k_int, k_enc, k_int, srslte::CIPHERING_ALGORITHM_ID_128_EEA2, srslte::INTEGRITY_ALGORITHM_ID_128_EIA2);
pdcp_rx.enable_integrity();
pdcp_rx.enable_encryption();
srslte::unique_byte_buffer_t sdu_act = allocate_unique_buffer(*pool);
srslte::unique_byte_buffer_t sdu_exp = allocate_unique_buffer(*pool);
memcpy(sdu_exp->msg, sdu2, SDU2_LEN);
sdu_exp->N_bytes = SDU2_LEN;
// Generate encripted and integrity protected PDUs
srslte::unique_byte_buffer_t rx_pdu7 = allocate_unique_buffer(*pool);
memcpy(rx_pdu7->msg, pdu7, PDU7_LEN);
rx_pdu7->N_bytes = PDU7_LEN;
// decript and check matching SDUs (out of order)
pdcp_rx.write_pdu(std::move(rx_pdu7));
gw_rx.get_last_pdu(sdu_act);
// Make sure out of order is not received until time out
TESTASSERT(gw_rx.rx_count == 0);
TESTASSERT(sdu_exp->N_bytes == sdu_act->N_bytes);
for (uint32_t j = 0; j < sdu_act->N_bytes; ++j) {
TESTASSERT(sdu_exp->msg[j] == sdu_act->msg[j]);
}
return 0;
}
// Setup all tests
int run_all_tests(srslte::byte_buffer_pool* pool)
{
@ -381,11 +425,12 @@ int run_all_tests(srslte::byte_buffer_pool* pool)
log.set_level(srslte::LOG_LEVEL_DEBUG);
log.set_hex_limit(128);
// TESTASSERT(test_tx_all(pool, &log) == 0);
// TESTASSERT(test_rx_in_sequence(4097, srslte::PDCP_SN_LEN_12, pool, &log) == 0);
TESTASSERT(test_tx_all(pool, &log) == 0);
TESTASSERT(test_rx_in_sequence(4097, srslte::PDCP_SN_LEN_12, pool, &log) == 0);
// TESTASSERT(test_rx_in_sequence(4294967297, srslte::PDCP_SN_LEN_12, pool, &log) == 0);
// TESTASSERT(test_rx_in_sequence(262145, srslte::PDCP_SN_LEN_18, pool, &log) == 0);
TESTASSERT(test_rx_in_sequence(262145, srslte::PDCP_SN_LEN_18, pool, &log) == 0);
TESTASSERT(test_rx_out_of_order(srslte::PDCP_SN_LEN_12, pool, &log) == 0);
TESTASSERT(test_rx_out_of_order_timeout(srslte::PDCP_SN_LEN_12, pool, &log) == 0);
return 0;
}