refactor RLC part#2

- move metrics into entities
- make configure interface return true/false on success/failure
- add own srslte mode type
master
Andre Puschmann 7 years ago
parent 8e8fab027b
commit 27d3d697df

@ -66,8 +66,7 @@ struct rlc_amd_retx_t{
};
class rlc_am
:public rlc_common
class rlc_am : public rlc_common
{
public:
rlc_am(uint32_t queue_len = 16);
@ -77,7 +76,7 @@ public:
srsue::pdcp_interface_rlc *pdcp_,
srsue::rrc_interface_rlc *rrc_,
mac_interface_timers *mac_timers);
void configure(srslte_rlc_config_t cnfg);
bool configure(srslte_rlc_config_t cnfg);
void reestablish();
void stop();
@ -96,6 +95,10 @@ public:
int read_pdu(uint8_t *payload, uint32_t nof_bytes);
void write_pdu(uint8_t *payload, uint32_t nof_bytes);
uint32_t get_num_tx_bytes();
uint32_t get_num_rx_bytes();
void reset_metrics();
private:
byte_buffer_pool *pool;
@ -128,6 +131,10 @@ private:
bool do_status;
rlc_status_pdu_t status;
// Metrics
uint32_t num_tx_bytes;
uint32_t num_rx_bytes;
/****************************************************************************
* Configurable parameters
* Ref: 3GPP TS 36.322 v10.0.0 Section 7

@ -161,7 +161,7 @@ public:
srsue::pdcp_interface_rlc *pdcp_,
srsue::rrc_interface_rlc *rrc_,
srslte::mac_interface_timers *mac_timers_) = 0;
virtual void configure(srslte_rlc_config_t cnfg) = 0;
virtual bool configure(srslte_rlc_config_t cnfg) = 0;
virtual void stop() = 0;
virtual void reestablish() = 0;
virtual void empty_queue() = 0;
@ -169,6 +169,10 @@ public:
virtual rlc_mode_t get_mode() = 0;
virtual uint32_t get_bearer() = 0;
virtual uint32_t get_num_tx_bytes() = 0;
virtual uint32_t get_num_rx_bytes() = 0;
virtual void reset_metrics() = 0;
// PDCP interface
virtual void write_sdu(byte_buffer_t *sdu) = 0;
virtual void write_sdu_nb(byte_buffer_t *sdu) = 0;

@ -28,11 +28,19 @@
#define SRSLTE_RLC_INTERFACE_H
// for custom constructors
#include "srslte/asn1/liblte_rrc.h"
#include <srslte/asn1/liblte_rrc.h>
namespace srslte {
typedef enum{
SRSLTE_RLC_MODE_TM = 0,
SRSLTE_RLC_MODE_UM,
SRSLTE_RLC_MODE_AM,
SRSLTE_RLC_MODE_N_ITEMS
} srslte_rlc_mode_t;
static const char srslte_rlc_mode_text[SRSLTE_RLC_MODE_N_ITEMS][20] = { "TM", "UM", "AM"};
typedef enum{
RLC_UMD_SN_SIZE_5_BITS = 0,
RLC_UMD_SN_SIZE_10_BITS,
@ -80,19 +88,22 @@ typedef struct {
class srslte_rlc_config_t
{
public:
LIBLTE_RRC_RLC_MODE_ENUM rlc_mode;
srslte_rlc_mode_t rlc_mode;
srslte_rlc_am_config_t am;
srslte_rlc_um_config_t um;
// Default ctor
srslte_rlc_config_t(): rlc_mode(LIBLTE_RRC_RLC_MODE_AM), am(), um() {};
srslte_rlc_config_t(): rlc_mode(SRSLTE_RLC_MODE_TM), am(), um() {};
// Constructor based on liblte's RLC config
srslte_rlc_config_t(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) : rlc_mode(cnfg->rlc_mode), am(), um()
srslte_rlc_config_t(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) : rlc_mode(SRSLTE_RLC_MODE_AM), am(), um()
{
// update RLC mode to internal mode struct
rlc_mode = (cnfg->rlc_mode == LIBLTE_RRC_RLC_MODE_AM) ? SRSLTE_RLC_MODE_AM : SRSLTE_RLC_MODE_UM;
switch(rlc_mode)
{
case LIBLTE_RRC_RLC_MODE_AM:
case SRSLTE_RLC_MODE_AM:
am.t_poll_retx = liblte_rrc_t_poll_retransmit_num[cnfg->ul_am_rlc.t_poll_retx];
am.poll_pdu = liblte_rrc_poll_pdu_num[cnfg->ul_am_rlc.poll_pdu];
am.poll_byte = liblte_rrc_poll_byte_num[cnfg->ul_am_rlc.poll_byte]*1000; // KB
@ -100,7 +111,7 @@ public:
am.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_am_rlc.t_reordering];
am.t_status_prohibit = liblte_rrc_t_status_prohibit_num[cnfg->dl_am_rlc.t_status_prohibit];
break;
case LIBLTE_RRC_RLC_MODE_UM_BI:
case SRSLTE_RLC_MODE_UM:
um.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_bi_rlc.t_reordering];
um.rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_bi_rlc.sn_field_len;
um.rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 16 : 512;
@ -108,16 +119,6 @@ public:
um.tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_bi_rlc.sn_field_len;
um.tx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.tx_sn_field_length) ? 32 : 1024;
break;
case LIBLTE_RRC_RLC_MODE_UM_UNI_UL:
um.tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_uni_rlc.sn_field_len;
um.tx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.tx_sn_field_length) ? 32 : 1024;
break;
case LIBLTE_RRC_RLC_MODE_UM_UNI_DL:
um.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_uni_rlc.t_reordering];
um.rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_uni_rlc.sn_field_len;
um.rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 16 : 512;
um.rx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 32 : 1024;
break;
default:
// Handle default case
break;
@ -128,7 +129,7 @@ public:
static srslte_rlc_config_t mch_config()
{
srslte_rlc_config_t cfg;
cfg.rlc_mode = LIBLTE_RRC_RLC_MODE_UM_UNI_DL;
cfg.rlc_mode = SRSLTE_RLC_MODE_UM;
cfg.um.t_reordering = 0;
cfg.um.rx_sn_field_length = RLC_UMD_SN_SIZE_5_BITS;
cfg.um.rx_window_size = 0;

@ -36,8 +36,7 @@
namespace srslte {
class rlc_tm
:public rlc_common
class rlc_tm : public rlc_common
{
public:
rlc_tm(uint32_t queue_len = 16);
@ -47,7 +46,7 @@ public:
srsue::pdcp_interface_rlc *pdcp_,
srsue::rrc_interface_rlc *rrc_,
mac_interface_timers *mac_timers);
void configure(srslte_rlc_config_t cnfg);
bool configure(srslte_rlc_config_t cnfg);
void stop();
void reestablish();
void empty_queue();
@ -55,6 +54,10 @@ public:
rlc_mode_t get_mode();
uint32_t get_bearer();
uint32_t get_num_tx_bytes();
uint32_t get_num_rx_bytes();
void reset_metrics();
// PDCP interface
void write_sdu(byte_buffer_t *sdu);
void write_sdu_nb(byte_buffer_t *sdu);
@ -75,6 +78,9 @@ private:
bool tx_enabled;
uint32_t num_tx_bytes;
uint32_t num_rx_bytes;
// Thread-safe queues for MAC messages
rlc_tx_queue ul_queue;
};

@ -55,7 +55,7 @@ public:
srsue::pdcp_interface_rlc *pdcp_,
srsue::rrc_interface_rlc *rrc_,
mac_interface_timers *mac_timers_);
void configure(srslte_rlc_config_t cnfg);
bool configure(srslte_rlc_config_t cnfg);
void reestablish();
void stop();
void empty_queue();
@ -75,6 +75,10 @@ public:
void write_pdu(uint8_t *payload, uint32_t nof_bytes);
int get_increment_sequence_num();
uint32_t get_num_tx_bytes();
uint32_t get_num_rx_bytes();
void reset_metrics();
private:
// Transmitter sub-class
@ -84,13 +88,15 @@ private:
rlc_um_tx(uint32_t queue_len);
~rlc_um_tx();
void init(srslte::log *log_);
void configure(srslte_rlc_config_t cfg, std::string rb_name);
bool configure(srslte_rlc_config_t cfg, std::string rb_name);
int build_data_pdu(uint8_t *payload, uint32_t nof_bytes);
void stop();
void reestablish();
void empty_queue();
void write_sdu(byte_buffer_t *sdu);
void try_write_sdu(byte_buffer_t *sdu);
uint32_t get_num_tx_bytes();
void reset_metrics();
uint32_t get_buffer_size_bytes();
private:
@ -119,6 +125,8 @@ private:
bool tx_enabled;
uint32_t num_tx_bytes;
// helper functions
void debug_state();
const char* get_rb_name();
@ -136,10 +144,12 @@ private:
srslte::mac_interface_timers *mac_timers_);
void stop();
void reestablish();
void configure(srslte_rlc_config_t cfg, std::string rb_name);
bool configure(srslte_rlc_config_t cfg, std::string rb_name);
void handle_data_pdu(uint8_t *payload, uint32_t nof_bytes);
void reassemble_rx_sdus();
bool inside_reordering_window(uint16_t sn);
uint32_t get_num_rx_bytes();
void reset_metrics();
// Timeout callback interface
void timer_expired(uint32_t timeout_id);
@ -163,12 +173,14 @@ private:
byte_buffer_t *rx_sdu;
uint32_t vr_ur_in_rx_sdu;
// Rx state variables
// Rx state variables and counter
uint32_t vr_ur; // Receive state. SN of earliest PDU still considered for reordering.
uint32_t vr_ux; // t_reordering state. SN following PDU which triggered t_reordering.
uint32_t vr_uh; // Highest rx state. SN following PDU with highest SN among rxed PDUs.
bool pdu_lost;
uint32_t num_rx_bytes;
// Upper layer handles and variables
srsue::pdcp_interface_rlc *pdcp;
srsue::rrc_interface_rlc *rrc;
@ -177,6 +189,8 @@ private:
// Mutexes
pthread_mutex_t mutex;
bool rx_enabled;
/****************************************************************************
* Timers
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
@ -196,6 +210,7 @@ private:
// Common variables needed by parent class
srsue::rrc_interface_rlc *rrc;
srslte::log *log;
uint32_t lcid;
srslte_rlc_um_config_t cfg;
std::string rb_name;

@ -61,6 +61,9 @@ rlc_am::rlc_am(uint32_t queue_len) : tx_sdu_queue(queue_len)
vr_ms = 0;
vr_h = 0;
num_tx_bytes = 0;
num_rx_bytes = 0;
pdu_without_poll = 0;
byte_without_poll = 0;
@ -88,13 +91,15 @@ void rlc_am::init(srslte::log *log_,
tx_enabled = true;
}
void rlc_am::configure(srslte_rlc_config_t cfg_)
bool rlc_am::configure(srslte_rlc_config_t cfg_)
{
cfg = cfg_.am;
log->warning("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, "
"t_reordering=%d, t_status_prohibit=%d\n",
rrc->get_rb_name(lcid).c_str(), cfg.t_poll_retx, cfg.poll_pdu, cfg.poll_byte, cfg.max_retx_thresh,
cfg.t_reordering, cfg.t_status_prohibit);
return true;
}
@ -363,6 +368,7 @@ unlock_and_return:
int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes)
{
pthread_mutex_lock(&mutex);
int pdu_size = 0;
log->debug("MAC opportunity - %d bytes\n", nof_bytes);
log->debug("tx_window size - %zu PDUs\n", tx_window.size());
@ -370,7 +376,8 @@ int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes)
// Tx STATUS if requested
if(do_status && !status_prohibited()) {
pthread_mutex_unlock(&mutex);
return build_status_pdu(payload, nof_bytes);
pdu_size = build_status_pdu(payload, nof_bytes);
goto unlock_and_exit;
}
// if tx_window is full and retx_queue empty, retransmit next PDU to be ack'ed
@ -390,25 +397,27 @@ int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes)
// RETX if required
if(retx_queue.size() > 0) {
int ret = build_retx_pdu(payload, nof_bytes);
if (ret > 0) {
pthread_mutex_unlock(&mutex);
return ret;
pdu_size = build_retx_pdu(payload, nof_bytes);
if (pdu_size > 0) {
goto unlock_and_exit;
}
}
// Build a PDU from SDUs
int ret = build_data_pdu(payload, nof_bytes);
pdu_size = build_data_pdu(payload, nof_bytes);
unlock_and_exit:
num_tx_bytes += pdu_size;
pthread_mutex_unlock(&mutex);
return ret;
return pdu_size;
}
void rlc_am::write_pdu(uint8_t *payload, uint32_t nof_bytes)
{
if(nof_bytes < 1)
return;
if (nof_bytes < 1) return;
pthread_mutex_lock(&mutex);
num_rx_bytes += nof_bytes;
if(rlc_am_is_control_pdu(payload)) {
handle_control_pdu(payload, nof_bytes);
@ -424,6 +433,25 @@ void rlc_am::write_pdu(uint8_t *payload, uint32_t nof_bytes)
pthread_mutex_unlock(&mutex);
}
uint32_t rlc_am::get_num_tx_bytes()
{
return num_tx_bytes;
}
uint32_t rlc_am::get_num_rx_bytes()
{
return num_rx_bytes;
}
void rlc_am::reset_metrics()
{
pthread_mutex_lock(&mutex);
num_rx_bytes = 0;
num_tx_bytes = 0;
pthread_mutex_unlock(&mutex);
}
/****************************************************************************
* Timer checks
***************************************************************************/

@ -35,6 +35,8 @@ rlc_tm::rlc_tm(uint32_t queue_len) : ul_queue(queue_len)
pdcp = NULL;
rrc = NULL;
lcid = 0;
num_tx_bytes = 0;
num_rx_bytes = 0;
pool = byte_buffer_pool::get_instance();
}
@ -56,16 +58,17 @@ void rlc_tm::init(srslte::log *log_,
tx_enabled = true;
}
void rlc_tm::configure(srslte_rlc_config_t cnfg)
bool rlc_tm::configure(srslte_rlc_config_t cnfg)
{
log->error("Attempted to configure TM RLC entity\n");
return true;
}
void rlc_tm::empty_queue()
{
// Drop all messages in TX queue
byte_buffer_t *buf;
while(ul_queue.try_read(&buf)) {
while (ul_queue.try_read(&buf)) {
pool->deallocate(buf);
}
ul_queue.reset();
@ -139,11 +142,26 @@ uint32_t rlc_tm::get_total_buffer_state()
return get_buffer_state();
}
uint32_t rlc_tm::get_num_tx_bytes()
{
return num_tx_bytes;
}
uint32_t rlc_tm::get_num_rx_bytes()
{
return num_rx_bytes;
}
void rlc_tm::reset_metrics()
{
num_tx_bytes = 0;
num_rx_bytes = 0;
}
int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes)
{
uint32_t pdu_size = ul_queue.size_tail_bytes();
if(pdu_size > nof_bytes)
{
if (pdu_size > nof_bytes) {
log->error("TX %s PDU size larger than MAC opportunity\n", rrc->get_rb_name(lcid).c_str());
return -1;
}
@ -156,6 +174,8 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes)
pool->deallocate(buf);
log->info_hex(payload, pdu_size, "TX %s, %s PDU, queue size=%d, bytes=%d",
rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM], ul_queue.size(), ul_queue.size_bytes());
num_tx_bytes += pdu_size;
return pdu_size;
} else {
log->warning("Queue empty while trying to read\n");
@ -174,6 +194,7 @@ void rlc_tm::write_pdu(uint8_t *payload, uint32_t nof_bytes)
memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes;
buf->set_timestamp();
num_rx_bytes += nof_bytes;
pdcp->write_pdu(lcid, buf);
} else {
log->error("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu().\n");

@ -37,6 +37,7 @@ rlc_um::rlc_um(uint32_t queue_len)
:lcid(0)
,tx(queue_len)
,rrc(NULL)
,log(NULL)
{
bzero(&cfg, sizeof(srslte_rlc_um_config_t));
}
@ -57,48 +58,48 @@ void rlc_um::init(srslte::log *log_,
rx.init(log_, lcid_, pdcp_, rrc_, mac_timers_);
lcid = lcid_;
rrc = rrc_; // needed to determine bearer name during configuration
log = log_;
}
void rlc_um::configure(srslte_rlc_config_t cnfg_)
bool rlc_um::configure(srslte_rlc_config_t cnfg_)
{
// determine bearer name and configure Rx/Tx objects
rb_name = get_rb_name(rrc, lcid, cnfg_.um.is_mrb);
rx.configure(cnfg_, rb_name);
tx.configure(cnfg_, rb_name);
if (not rx.configure(cnfg_, rb_name)) {
return false;
}
if (not tx.configure(cnfg_, rb_name)) {
return false;
}
log->warning("%s configured in %s mode: t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n",
rb_name.c_str(), srslte_rlc_mode_text[cnfg_.rlc_mode],
cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length], rlc_umd_sn_size_num[cfg.rx_sn_field_length]);
// store config
cfg = cnfg_.um;
return true;
}
void rlc_um::rlc_um_rx::configure(srslte_rlc_config_t cnfg_, std::string rb_name_)
bool rlc_um::rlc_um_rx::configure(srslte_rlc_config_t cnfg_, std::string rb_name_)
{
cfg = cnfg_.um;
rb_name = rb_name_;
switch(cnfg_.rlc_mode) {
case LIBLTE_RRC_RLC_MODE_UM_BI:
log->warning("%s configured in %s mode: "
"t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n",
get_rb_name(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode],
cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length], rlc_umd_sn_size_num[cfg.rx_sn_field_length]);
break;
case LIBLTE_RRC_RLC_MODE_UM_UNI_UL:
log->warning("%s configured in %s mode: tx_sn_field_length=%u bits\n",
get_rb_name(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode],
rlc_umd_sn_size_num[cfg.rx_sn_field_length]);
break;
case LIBLTE_RRC_RLC_MODE_UM_UNI_DL:
log->warning("%s configured in %s mode: "
"t_reordering=%d ms, rx_sn_field_length=%u bits\n",
get_rb_name(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode],
cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length]);
break;
default:
log->error("RLC configuration mode not recognized\n");
if (cfg.rx_mod == 0) {
log->error("Error configuring %s RLC UM: rx_mod==0\n", get_rb_name());
return false;
}
rb_name = rb_name_;
rx_enabled = true;
return true;
}
@ -175,6 +176,22 @@ void rlc_um::write_pdu(uint8_t *payload, uint32_t nof_bytes)
rx.handle_data_pdu(payload, nof_bytes);
}
uint32_t rlc_um::get_num_tx_bytes()
{
return tx.get_num_tx_bytes();
}
uint32_t rlc_um::get_num_rx_bytes()
{
return rx.get_num_rx_bytes();
}
void rlc_um::reset_metrics()
{
tx.reset_metrics();
rx.reset_metrics();
}
/****************************************************************************
* Helper functions
@ -203,6 +220,7 @@ rlc_um::rlc_um_tx::rlc_um_tx(uint32_t queue_len)
,tx_sdu(NULL)
,vt_us(0)
,tx_enabled(false)
,num_tx_bytes(0)
{
pthread_mutex_init(&mutex, NULL);
}
@ -217,17 +235,26 @@ rlc_um::rlc_um_tx::~rlc_um_tx()
void rlc_um::rlc_um_tx::init(srslte::log *log_)
{
log = log_;
tx_enabled = true;
}
void rlc_um::rlc_um_tx::configure(srslte_rlc_config_t cnfg_, std::string rb_name_)
bool rlc_um::rlc_um_tx::configure(srslte_rlc_config_t cnfg_, std::string rb_name_)
{
cfg = cnfg_.um;
if (cfg.tx_mod == 0) {
log->error("Error configuring %s RLC UM: tx_mod==0\n", get_rb_name());
return false;
}
if(cfg.is_mrb){
tx_sdu_queue.resize(512);
}
rb_name = rb_name_;
tx_enabled = true;
return true;
}
@ -266,6 +293,20 @@ void rlc_um::rlc_um_tx::empty_queue()
}
uint32_t rlc_um::rlc_um_tx::get_num_tx_bytes()
{
return num_tx_bytes;
}
void rlc_um::rlc_um_tx::reset_metrics()
{
pthread_mutex_lock(&mutex);
num_tx_bytes = 0;
pthread_mutex_unlock(&mutex);
}
uint32_t rlc_um::rlc_um_tx::get_buffer_size_bytes()
{
// Bytes needed for tx SDUs
@ -434,6 +475,8 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
debug_state();
num_tx_bytes += ret;
pthread_mutex_unlock(&mutex);
return ret;
}
@ -469,6 +512,8 @@ rlc_um::rlc_um_rx::rlc_um_rx()
,pdu_lost(false)
,mac_timers(NULL)
,lcid(0)
,num_rx_bytes(0)
,rx_enabled(false)
{
pthread_mutex_init(&mutex, NULL);
}
@ -508,6 +553,8 @@ void rlc_um::rlc_um_rx::stop()
vr_ux = 0;
vr_uh = 0;
pdu_lost = false;
rx_enabled = false;
if(rx_sdu) {
pool->deallocate(rx_sdu);
rx_sdu = NULL;
@ -531,10 +578,18 @@ void rlc_um::rlc_um_rx::stop()
void rlc_um::rlc_um_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
{
pthread_mutex_lock(&mutex);
rlc_umd_pdu_t pdu;
int header_len = 0;
std::map<uint32_t, rlc_umd_pdu_t>::iterator it;
rlc_umd_pdu_header_t header;
if (!rx_enabled) {
goto unlock_and_exit;
}
num_rx_bytes += nof_bytes;
rlc_um_read_data_pdu_header(payload, nof_bytes, cfg.rx_sn_field_length, &header);
log->info_hex(payload, nof_bytes, "RX %s Rx data PDU SN: %d", get_rb_name(), header.sn);
@ -596,7 +651,7 @@ void rlc_um::rlc_um_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
debug_state();
unlock_and_exit:
unlock_and_exit:
pthread_mutex_unlock(&mutex);
}
@ -814,6 +869,20 @@ bool rlc_um::rlc_um_rx::inside_reordering_window(uint16_t sn)
}
uint32_t rlc_um::rlc_um_rx::get_num_rx_bytes()
{
return num_rx_bytes;
}
void rlc_um::rlc_um_rx::reset_metrics()
{
pthread_mutex_lock(&mutex);
num_rx_bytes = 0;
pthread_mutex_unlock(&mutex);
}
/****************************************************************************
* Timeout callback interface
***************************************************************************/

@ -169,6 +169,10 @@ void basic_test()
assert(tester.sdus[i]->N_bytes == 1);
assert(*(tester.sdus[i]->msg) == i);
}
// Check statistics
assert(rlc1.get_num_tx_bytes() == rlc2.get_num_rx_bytes());
assert(rlc2.get_num_tx_bytes() == rlc1.get_num_rx_bytes());
}
void concat_test()
@ -234,6 +238,10 @@ void concat_test()
assert(tester.sdus[i]->N_bytes == 1);
assert(*(tester.sdus[i]->msg) == i);
}
// check statistics
assert(rlc1.get_num_tx_bytes() == rlc2.get_num_rx_bytes());
assert(rlc2.get_num_tx_bytes() == rlc1.get_num_rx_bytes());
}
void segment_test()
@ -317,6 +325,9 @@ void segment_test()
for(int j=0;j<10;j++)
assert(tester.sdus[i]->msg[j] == j);
}
assert(rlc1.get_num_tx_bytes() == rlc2.get_num_rx_bytes());
assert(rlc2.get_num_tx_bytes() == rlc1.get_num_rx_bytes());
}
void retx_test()

@ -325,7 +325,7 @@ void stress_test(stress_test_args_t args)
srslte_rlc_config_t cnfg_;
if (args.mode == "AM") {
// config RLC AM bearer
cnfg_.rlc_mode = LIBLTE_RRC_RLC_MODE_AM;
cnfg_.rlc_mode = SRSLTE_RLC_MODE_AM;
cnfg_.am.max_retx_thresh = 4;
cnfg_.am.poll_byte = 25*1000;
cnfg_.am.poll_pdu = 4;
@ -334,7 +334,7 @@ void stress_test(stress_test_args_t args)
cnfg_.am.t_status_prohibit = 5;
} else if (args.mode == "UM") {
// config UM bearer
cnfg_.rlc_mode = LIBLTE_RRC_RLC_MODE_UM_BI;
cnfg_.rlc_mode = SRSLTE_RLC_MODE_UM;
cnfg_.um.t_reordering = 5;
cnfg_.um.rx_mod = 32;
cnfg_.um.rx_sn_field_length = RLC_UMD_SN_SIZE_5_BITS;
@ -388,15 +388,23 @@ void stress_test(stress_test_args_t args)
pcap.close();
}
printf("RLC1 received %d SDUs in %ds (%.2f PDU/s)\n",
rlc_metrics_t metrics;
rlc1.get_metrics(metrics);
printf("RLC1 received %d SDUs in %ds (%.2f PDU/s), Throughput: DL=%4.2f Mbps, UL=%4.2f Mbps\n",
tester1.get_nof_rx_pdus(),
args.test_duration_sec,
(float)tester1.get_nof_rx_pdus()/args.test_duration_sec);
(float)tester1.get_nof_rx_pdus()/args.test_duration_sec,
metrics.dl_tput_mbps,
metrics.ul_tput_mbps);
printf("RLC2 received %d SDUs in %ds (%.2f PDU/s)\n",
rlc2.get_metrics(metrics);
printf("RLC2 received %d SDUs in %ds (%.2f PDU/s), Throughput: DL=%4.2f Mbps, UL=%4.2f Mbps\n",
tester2.get_nof_rx_pdus(),
args.test_duration_sec,
(float)tester2.get_nof_rx_pdus()/args.test_duration_sec);
(float)tester2.get_nof_rx_pdus()/args.test_duration_sec,
metrics.dl_tput_mbps,
metrics.ul_tput_mbps);
}

@ -130,8 +130,8 @@ void basic_test()
cnfg.dl_um_bi_rlc.sn_field_len = LIBLTE_RRC_SN_FIELD_LENGTH_SIZE10;
cnfg.ul_um_bi_rlc.sn_field_len = LIBLTE_RRC_SN_FIELD_LENGTH_SIZE10;
rlc1.configure(&cnfg);
rlc2.configure(&cnfg);
assert(rlc1.configure(&cnfg) == true);
assert(rlc2.configure(&cnfg) == true);
tester.set_expected_sdu_len(1);

@ -123,7 +123,7 @@ void rlc::add_bearer_mrb(uint16_t rnti, uint32_t lcid)
{
pthread_rwlock_rdlock(&rwlock);
if (users.count(rnti)) {
users[rnti].rlc->add_bearer_mrb_enb(lcid);
users[rnti].rlc->add_bearer_mrb(lcid);
}
pthread_rwlock_unlock(&rwlock);
}

Loading…
Cancel
Save