rework bearer/LCID handling

This is a larger patch that reworks the LCID handling throughout the
code.

- It first moves the RB/LCID mapping out of common.h into the RRC object
  because different RATs may have different mappings.
- It adds a interface to RRC that other objects like RLC/PDCP/etc. may
  use to get the bearer name of a specific LCID.
- The patch also introduces a PDCP config class.
master
Andre Puschmann 8 years ago
parent 60da04ef58
commit 8dbabb2834

@ -83,32 +83,6 @@ static const char error_text[ERROR_N_ITEMS][20] = { "None",
"Can't start", "Can't start",
"Already started"}; "Already started"};
typedef enum{
RB_ID_SRB0 = 0,
RB_ID_SRB1,
RB_ID_SRB2,
RB_ID_DRB1,
RB_ID_DRB2,
RB_ID_DRB3,
RB_ID_DRB4,
RB_ID_DRB5,
RB_ID_DRB6,
RB_ID_DRB7,
RB_ID_DRB8,
RB_ID_N_ITEMS,
}rb_id_t;
static const char rb_id_text[RB_ID_N_ITEMS][20] = { "SRB0",
"SRB1",
"SRB2",
"DRB1",
"DRB2",
"DRB3",
"DRB4",
"DRB5",
"DRB6",
"DRB7",
"DRB8"};
/****************************************************************************** /******************************************************************************
* Byte and Bit buffers * Byte and Bit buffers
* *

@ -28,9 +28,30 @@
#define INTERFACE_COMMON_H #define INTERFACE_COMMON_H
#include "srslte/common/timers.h" #include "srslte/common/timers.h"
#include "srslte/common/security.h"
namespace srslte { namespace srslte {
class srslte_pdcp_config_t
{
public:
srslte_pdcp_config_t(bool is_control_ = false)
:direction(SECURITY_DIRECTION_UPLINK)
,is_control(is_control_)
,is_data(false)
,do_security(false)
,sn_len(12) {}
u_int8_t direction;
bool is_control;
bool is_data;
bool do_security;
uint8_t sn_len;
// TODO: Support the following configurations
// bool do_rohc;
};
class mac_interface_timers class mac_interface_timers
{ {
public: public:

@ -132,6 +132,7 @@ public:
virtual uint16_t get_mcc() = 0; virtual uint16_t get_mcc() = 0;
virtual uint16_t get_mnc() = 0; virtual uint16_t get_mnc() = 0;
virtual void enable_capabilities() = 0; virtual void enable_capabilities() = 0;
virtual std::string get_rb_name(uint32_t lcid) = 0;
}; };
// RRC interface for GW // RRC interface for GW
@ -151,6 +152,7 @@ public:
virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu) = 0; virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu) = 0;
virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu) = 0; virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu) = 0;
virtual void write_pdu_pcch(srslte::byte_buffer_t *pdu) = 0; virtual void write_pdu_pcch(srslte::byte_buffer_t *pdu) = 0;
virtual std::string get_rb_name(uint32_t lcid) = 0;
}; };
// RRC interface for RLC // RRC interface for RLC
@ -158,6 +160,7 @@ class rrc_interface_rlc
{ {
public: public:
virtual void max_retx_attempted() = 0; virtual void max_retx_attempted() = 0;
virtual std::string get_rb_name(uint32_t lcid) = 0;
}; };
// PDCP interface for GW // PDCP interface for GW
@ -173,7 +176,7 @@ class pdcp_interface_rrc
public: public:
virtual void reset() = 0; virtual void reset() = 0;
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg=NULL) = 0; virtual void add_bearer(uint32_t lcid, srslte::srslte_pdcp_config_t cnfg = srslte::srslte_pdcp_config_t()) = 0;
virtual void config_security(uint32_t lcid, virtual void config_security(uint32_t lcid,
uint8_t *k_rrc_enc_, uint8_t *k_rrc_enc_,
uint8_t *k_rrc_int_, uint8_t *k_rrc_int_,

@ -46,13 +46,14 @@ public:
srsue::rrc_interface_pdcp *rrc_, srsue::rrc_interface_pdcp *rrc_,
srsue::gw_interface_pdcp *gw_, srsue::gw_interface_pdcp *gw_,
log *pdcp_log_, log *pdcp_log_,
uint32_t lcid_,
uint8_t direction_); uint8_t direction_);
void stop(); void stop();
// RRC interface // RRC interface
void reset(); void reset();
void write_sdu(uint32_t lcid, byte_buffer_t *sdu); void write_sdu(uint32_t lcid, byte_buffer_t *sdu);
void add_bearer(uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg = NULL); void add_bearer(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t());
void config_security(uint32_t lcid, void config_security(uint32_t lcid,
uint8_t *k_rrc_enc, uint8_t *k_rrc_enc,
uint8_t *k_rrc_int, uint8_t *k_rrc_int,
@ -72,6 +73,7 @@ private:
log *pdcp_log; log *pdcp_log;
pdcp_entity pdcp_array[SRSLTE_N_RADIO_BEARERS]; pdcp_entity pdcp_array[SRSLTE_N_RADIO_BEARERS];
uint32_t lcid; // default LCID that is maintained active by PDCP instance
uint8_t direction; uint8_t direction;
bool valid_lcid(uint32_t lcid); bool valid_lcid(uint32_t lcid);

@ -67,9 +67,7 @@ public:
srsue::gw_interface_pdcp *gw_, srsue::gw_interface_pdcp *gw_,
srslte::log *log_, srslte::log *log_,
uint32_t lcid_, uint32_t lcid_,
uint8_t direction_, srslte_pdcp_config_t cfg_);
LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg = NULL
);
void reset(); void reset();
bool is_active(); bool is_active();
@ -94,12 +92,7 @@ private:
bool active; bool active;
uint32_t lcid; uint32_t lcid;
bool do_security; srslte_pdcp_config_t cfg;
u_int8_t direction;
uint8_t sn_len;
// TODO: Support the following configurations
// bool do_rohc;
uint32_t rx_count; uint32_t rx_count;
uint32_t tx_count; uint32_t tx_count;

@ -55,13 +55,15 @@ public:
srsue::rrc_interface_rlc *rrc_, srsue::rrc_interface_rlc *rrc_,
srsue::ue_interface *ue_, srsue::ue_interface *ue_,
log *rlc_log_, log *rlc_log_,
mac_interface_timers *mac_timers_); mac_interface_timers *mac_timers_,
uint32_t lcid_);
void stop(); void stop();
void get_metrics(rlc_metrics_t &m); void get_metrics(rlc_metrics_t &m);
// PDCP interface // PDCP interface
void write_sdu(uint32_t lcid, byte_buffer_t *sdu); void write_sdu(uint32_t lcid, byte_buffer_t *sdu);
std::string get_rb_name(uint32_t lcid);
// MAC interface // MAC interface
uint32_t get_buffer_state(uint32_t lcid); uint32_t get_buffer_state(uint32_t lcid);
@ -87,6 +89,7 @@ private:
srslte::mac_interface_timers *mac_timers; srslte::mac_interface_timers *mac_timers;
srsue::ue_interface *ue; srsue::ue_interface *ue;
srslte::rlc_entity rlc_array[SRSLTE_N_RADIO_BEARERS]; srslte::rlc_entity rlc_array[SRSLTE_N_RADIO_BEARERS];
uint32_t default_lcid;
long ul_tput_bytes[SRSLTE_N_RADIO_BEARERS]; long ul_tput_bytes[SRSLTE_N_RADIO_BEARERS];
long dl_tput_bytes[SRSLTE_N_RADIO_BEARERS]; long dl_tput_bytes[SRSLTE_N_RADIO_BEARERS];

@ -32,15 +32,16 @@ namespace srslte {
pdcp::pdcp() pdcp::pdcp()
{} {}
void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, log *pdcp_log_, uint8_t direction_) void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, log *pdcp_log_, uint32_t lcid_, uint8_t direction_)
{ {
rlc = rlc_; rlc = rlc_;
rrc = rrc_; rrc = rrc_;
gw = gw_; gw = gw_;
pdcp_log = pdcp_log_; pdcp_log = pdcp_log_;
lcid = lcid_;
direction = direction_; direction = direction_;
pdcp_array[0].init(rlc, rrc, gw, pdcp_log, RB_ID_SRB0, direction); // SRB0 pdcp_array[0].init(rlc, rrc, gw, pdcp_log, lcid, direction);
} }
void pdcp::stop() void pdcp::stop()
@ -52,7 +53,7 @@ void pdcp::reset()
pdcp_array[i].reset(); pdcp_array[i].reset();
} }
pdcp_array[0].init(rlc, rrc, gw, pdcp_log, RB_ID_SRB0, direction); // SRB0 pdcp_array[0].init(rlc, rrc, gw, pdcp_log, lcid, direction);
} }
/******************************************************************************* /*******************************************************************************
@ -64,17 +65,17 @@ void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu)
pdcp_array[lcid].write_sdu(sdu); pdcp_array[lcid].write_sdu(sdu);
} }
void pdcp::add_bearer(uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg) void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg)
{ {
if(lcid < 0 || lcid >= SRSLTE_N_RADIO_BEARERS) { if(lcid >= SRSLTE_N_RADIO_BEARERS) {
pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid);
return; return;
} }
if (!pdcp_array[lcid].is_active()) { if (!pdcp_array[lcid].is_active()) {
pdcp_array[lcid].init(rlc, rrc, gw, pdcp_log, lcid, direction, cnfg); pdcp_array[lcid].init(rlc, rrc, gw, pdcp_log, lcid, cfg);
pdcp_log->info("Added bearer %s\n", rb_id_text[lcid]); pdcp_log->info("Added bearer %s\n", rrc->get_rb_name(lcid).c_str());
} else { } else {
pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rb_id_text[lcid]); pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid));
} }
} }
@ -116,7 +117,7 @@ void pdcp::write_pdu_pcch(byte_buffer_t *sdu)
*******************************************************************************/ *******************************************************************************/
bool pdcp::valid_lcid(uint32_t lcid) bool pdcp::valid_lcid(uint32_t lcid)
{ {
if(lcid < 0 || lcid >= SRSLTE_N_RADIO_BEARERS) { if(lcid >= SRSLTE_N_RADIO_BEARERS) {
pdcp_log->error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); pdcp_log->error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid);
return false; return false;
} }

@ -34,8 +34,6 @@ pdcp_entity::pdcp_entity()
:active(false) :active(false)
,tx_count(0) ,tx_count(0)
,rx_count(0) ,rx_count(0)
,do_security(false)
,sn_len(12)
{ {
pool = byte_buffer_pool::get_instance(); pool = byte_buffer_pool::get_instance();
} }
@ -45,38 +43,27 @@ void pdcp_entity::init(srsue::rlc_interface_pdcp *rlc_,
srsue::gw_interface_pdcp *gw_, srsue::gw_interface_pdcp *gw_,
srslte::log *log_, srslte::log *log_,
uint32_t lcid_, uint32_t lcid_,
u_int8_t direction_, srslte_pdcp_config_t cfg_)
LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg)
{ {
rlc = rlc_; rlc = rlc_;
rrc = rrc_; rrc = rrc_;
gw = gw_; gw = gw_;
log = log_; log = log_;
lcid = lcid_; lcid = lcid_;
direction = direction_; cfg = cfg_;
active = true; active = true;
tx_count = 0; tx_count = 0;
rx_count = 0; rx_count = 0;
do_security = false;
if(cnfg) log->debug("Init %s\n", rrc->get_rb_name(lcid).c_str());
{
if(cnfg->rlc_um_pdcp_sn_size_present) {
if(LIBLTE_RRC_PDCP_SN_SIZE_7_BITS == cnfg->rlc_um_pdcp_sn_size) {
sn_len = 7;
}
}
// TODO: handle remainder of cnfg
}
log->debug("Init %s\n", rb_id_text[lcid]);
} }
void pdcp_entity::reset() void pdcp_entity::reset()
{ {
active = false; active = false;
if(log) if(log)
log->debug("Reset %s\n", rb_id_text[lcid]); log->debug("Reset %s\n", rrc->get_rb_name(lcid).c_str());
} }
bool pdcp_entity::is_active() bool pdcp_entity::is_active()
@ -87,44 +74,32 @@ bool pdcp_entity::is_active()
// RRC interface // RRC interface
void pdcp_entity::write_sdu(byte_buffer_t *sdu) void pdcp_entity::write_sdu(byte_buffer_t *sdu)
{ {
log->info_hex(sdu->msg, sdu->N_bytes, "TX %s SDU, do_security = %s", rb_id_text[lcid], (do_security)?"true":"false"); log->info_hex(sdu->msg, sdu->N_bytes, "TX %s SDU, do_security = %s", rrc->get_rb_name(lcid).c_str(), (cfg.do_security)?"true":"false");
// Handle SRB messages if (cfg.is_control) {
switch(lcid)
{
case RB_ID_SRB0:
rlc->write_sdu(lcid, sdu);
break;
case RB_ID_SRB1: // Intentional fall-through
case RB_ID_SRB2:
pdcp_pack_control_pdu(tx_count, sdu); pdcp_pack_control_pdu(tx_count, sdu);
if(do_security) if(cfg.do_security)
{ {
integrity_generate(&k_rrc_int[16], integrity_generate(&k_rrc_int[16],
tx_count, tx_count,
lcid-1, lcid-1,
direction, cfg.direction,
sdu->msg, sdu->msg,
sdu->N_bytes-4, sdu->N_bytes-4,
&sdu->msg[sdu->N_bytes-4]); &sdu->msg[sdu->N_bytes-4]);
} }
tx_count++; tx_count++;
rlc->write_sdu(lcid, sdu);
break;
} }
// Handle DRB messages if (cfg.is_data) {
if(lcid >= RB_ID_DRB1) if(12 == cfg.sn_len) {
{
if(12 == sn_len)
{
pdcp_pack_data_pdu_long_sn(tx_count++, sdu); pdcp_pack_data_pdu_long_sn(tx_count++, sdu);
} else { } else {
pdcp_pack_data_pdu_short_sn(tx_count++, sdu); pdcp_pack_data_pdu_short_sn(tx_count++, sdu);
} }
rlc->write_sdu(lcid, sdu);
} }
rlc->write_sdu(lcid, sdu);
} }
void pdcp_entity::config_security(uint8_t *k_rrc_enc_, void pdcp_entity::config_security(uint8_t *k_rrc_enc_,
@ -132,7 +107,7 @@ void pdcp_entity::config_security(uint8_t *k_rrc_enc_,
CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, CIPHERING_ALGORITHM_ID_ENUM cipher_algo_,
INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) INTEGRITY_ALGORITHM_ID_ENUM integ_algo_)
{ {
do_security = true; cfg.do_security = true;
for(int i=0; i<32; i++) for(int i=0; i<32; i++)
{ {
k_rrc_enc[i] = k_rrc_enc_[i]; k_rrc_enc[i] = k_rrc_enc_[i];
@ -145,37 +120,32 @@ void pdcp_entity::config_security(uint8_t *k_rrc_enc_,
// RLC interface // RLC interface
void pdcp_entity::write_pdu(byte_buffer_t *pdu) void pdcp_entity::write_pdu(byte_buffer_t *pdu)
{ {
// Handle SRB messages
switch(lcid)
{
case RB_ID_SRB0:
// Simply pass on to RRC
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU", rb_id_text[lcid]);
rrc->write_pdu(RB_ID_SRB0, pdu);
break;
case RB_ID_SRB1: // Intentional fall-through
case RB_ID_SRB2:
uint32_t sn;
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU", rb_id_text[lcid]);
pdcp_unpack_control_pdu(pdu, &sn);
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s SDU SN: %d",
rb_id_text[lcid], sn);
rrc->write_pdu(lcid, pdu);
break;
}
// Handle DRB messages
if(lcid >= RB_ID_DRB1)
{
if (cfg.is_data) {
uint32_t sn; uint32_t sn;
if(12 == sn_len) if(12 == cfg.sn_len)
{ {
pdcp_unpack_data_pdu_long_sn(pdu, &sn); pdcp_unpack_data_pdu_long_sn(pdu, &sn);
} else { } else {
pdcp_unpack_data_pdu_short_sn(pdu, &sn); pdcp_unpack_data_pdu_short_sn(pdu, &sn);
} }
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU: %d", rb_id_text[lcid], sn); log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU: %d", rrc->get_rb_name(lcid).c_str(), sn);
gw->write_pdu(lcid, pdu); gw->write_pdu(lcid, pdu);
} else {
if (cfg.is_control) {
uint32_t sn;
pdcp_unpack_control_pdu(pdu, &sn);
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s SDU SN: %d",
rrc->get_rb_name(lcid).c_str(), sn);
} else {
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU", rrc->get_rb_name(lcid).c_str());
}
// pass to RRC
rrc->write_pdu(lcid, pdu);
} }
} }

@ -41,18 +41,20 @@ void rlc::init(srsue::pdcp_interface_rlc *pdcp_,
srsue::rrc_interface_rlc *rrc_, srsue::rrc_interface_rlc *rrc_,
srsue::ue_interface *ue_, srsue::ue_interface *ue_,
log *rlc_log_, log *rlc_log_,
mac_interface_timers *mac_timers_) mac_interface_timers *mac_timers_,
uint32_t lcid_)
{ {
pdcp = pdcp_; pdcp = pdcp_;
rrc = rrc_; rrc = rrc_;
ue = ue_; ue = ue_;
rlc_log = rlc_log_; rlc_log = rlc_log_;
mac_timers = mac_timers_; mac_timers = mac_timers_;
default_lcid = lcid_;
gettimeofday(&metrics_time[1], NULL); gettimeofday(&metrics_time[1], NULL);
reset_metrics(); reset_metrics();
rlc_array[0].init(RLC_MODE_TM, rlc_log, RB_ID_SRB0, pdcp, rrc, mac_timers); // SRB0 rlc_array[0].init(RLC_MODE_TM, rlc_log, default_lcid, pdcp, rrc, mac_timers); // SRB0
} }
void rlc::reset_metrics() void rlc::reset_metrics()
@ -97,7 +99,7 @@ void rlc::reset()
rlc_array[i].reset(); rlc_array[i].reset();
} }
rlc_array[0].init(RLC_MODE_TM, rlc_log, RB_ID_SRB0, pdcp, rrc, mac_timers); // SRB0 rlc_array[0].init(RLC_MODE_TM, rlc_log, default_lcid, pdcp, rrc, mac_timers); // SRB0
} }
/******************************************************************************* /*******************************************************************************
@ -110,6 +112,11 @@ void rlc::write_sdu(uint32_t lcid, byte_buffer_t *sdu)
} }
} }
std::string rlc::get_rb_name(uint32_t lcid)
{
return rrc->get_rb_name(lcid);
}
/******************************************************************************* /*******************************************************************************
MAC interface MAC interface
*******************************************************************************/ *******************************************************************************/
@ -188,7 +195,7 @@ void rlc::add_bearer(uint32_t lcid)
{ {
// No config provided - use defaults for lcid // No config provided - use defaults for lcid
LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg; LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg;
if(RB_ID_SRB1 == lcid || RB_ID_SRB2 == lcid) if(default_lcid == lcid || (default_lcid+1) == lcid)
{ {
if (!rlc_array[lcid].active()) { if (!rlc_array[lcid].active()) {
cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM; cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM;
@ -200,11 +207,11 @@ void rlc::add_bearer(uint32_t lcid)
cnfg.dl_am_rlc.t_status_prohibit = LIBLTE_RRC_T_STATUS_PROHIBIT_MS0; cnfg.dl_am_rlc.t_status_prohibit = LIBLTE_RRC_T_STATUS_PROHIBIT_MS0;
add_bearer(lcid, &cnfg); add_bearer(lcid, &cnfg);
} else { } else {
rlc_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rb_id_text[lcid]); rlc_log->warning("Bearer %s already configured. Reconfiguration not supported\n", get_rb_name(lcid).c_str());
} }
}else{ }else{
rlc_log->error("Radio bearer %s does not support default RLC configuration.", rlc_log->error("Radio bearer %s does not support default RLC configuration.",
rb_id_text[lcid]); get_rb_name(lcid).c_str());
} }
} }
@ -218,7 +225,7 @@ void rlc::add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg)
if (!rlc_array[lcid].active()) { if (!rlc_array[lcid].active()) {
rlc_log->info("Adding radio bearer %s with mode %s\n", rlc_log->info("Adding radio bearer %s with mode %s\n",
rb_id_text[lcid], liblte_rrc_rlc_mode_text[cnfg->rlc_mode]); get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode]);
switch(cnfg->rlc_mode) switch(cnfg->rlc_mode)
{ {
case LIBLTE_RRC_RLC_MODE_AM: case LIBLTE_RRC_RLC_MODE_AM:
@ -238,7 +245,7 @@ void rlc::add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg)
return; return;
} }
} else { } else {
rlc_log->warning("Bearer %s already created.\n", rb_id_text[lcid]); rlc_log->warning("Bearer %s already created.\n", get_rb_name(lcid).c_str());
} }
rlc_array[lcid].configure(cnfg); rlc_array[lcid].configure(cnfg);

@ -86,7 +86,7 @@ void rlc_am::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg)
log->info("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, " log->info("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, "
"t_reordering=%d, t_status_prohibit=%d\n", "t_reordering=%d, t_status_prohibit=%d\n",
rb_id_text[lcid], t_poll_retx, poll_pdu, poll_byte, max_retx_thresh, rrc->get_rb_name(lcid).c_str(), t_poll_retx, poll_pdu, poll_byte, max_retx_thresh,
t_reordering, t_status_prohibit); t_reordering, t_status_prohibit);
} }
@ -176,7 +176,7 @@ uint32_t rlc_am::get_bearer()
void rlc_am::write_sdu(byte_buffer_t *sdu) void rlc_am::write_sdu(byte_buffer_t *sdu)
{ {
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rb_id_text[lcid]); log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rrc->get_rb_name(lcid).c_str());
tx_sdu_queue.write(sdu); tx_sdu_queue.write(sdu);
} }
@ -347,7 +347,7 @@ void rlc_am::check_reordering_timeout()
if(reordering_timeout.is_running() && reordering_timeout.expired()) if(reordering_timeout.is_running() && reordering_timeout.expired())
{ {
reordering_timeout.reset(); reordering_timeout.reset();
log->debug("%s reordering timeout expiry - updating vr_ms\n", rb_id_text[lcid]); log->debug("%s reordering timeout expiry - updating vr_ms\n", rrc->get_rb_name(lcid).c_str());
// 36.322 v10 Section 5.1.3.2.4 // 36.322 v10 Section 5.1.3.2.4
vr_ms = vr_x; vr_ms = vr_x;
@ -409,7 +409,7 @@ int rlc_am::build_status_pdu(uint8_t *payload, uint32_t nof_bytes)
if(pdu_len > 0 && nof_bytes >= (uint32_t)pdu_len) if(pdu_len > 0 && nof_bytes >= (uint32_t)pdu_len)
{ {
log->info("%s Tx status PDU - %s\n", log->info("%s Tx status PDU - %s\n",
rb_id_text[lcid], rlc_am_to_string(&status).c_str()); rrc->get_rb_name(lcid).c_str(), rlc_am_to_string(&status).c_str());
do_status = false; do_status = false;
poll_received = false; poll_received = false;
@ -420,7 +420,7 @@ int rlc_am::build_status_pdu(uint8_t *payload, uint32_t nof_bytes)
return rlc_am_write_status_pdu(&status, payload); return rlc_am_write_status_pdu(&status, payload);
}else{ }else{
log->warning("%s Cannot tx status PDU - %d bytes available, %d bytes required\n", log->warning("%s Cannot tx status PDU - %d bytes available, %d bytes required\n",
rb_id_text[lcid], nof_bytes, pdu_len); rrc->get_rb_name(lcid).c_str(), nof_bytes, pdu_len);
return 0; return 0;
} }
} }
@ -437,7 +437,7 @@ int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes)
// Is resegmentation needed? // Is resegmentation needed?
if(retx.is_segment || required_buffer_size(retx) > (int)nof_bytes) { if(retx.is_segment || required_buffer_size(retx) > (int)nof_bytes) {
log->debug("%s build_retx_pdu - resegmentation required\n", rb_id_text[lcid]); log->debug("%s build_retx_pdu - resegmentation required\n", rrc->get_rb_name(lcid).c_str());
return build_segment(payload, nof_bytes, retx); return build_segment(payload, nof_bytes, retx);
} }
@ -462,7 +462,7 @@ int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes)
if(tx_window[retx.sn].retx_count >= max_retx_thresh) if(tx_window[retx.sn].retx_count >= max_retx_thresh)
rrc->max_retx_attempted(); rrc->max_retx_attempted();
log->info("%s Retx PDU scheduled for tx. SN: %d, retx count: %d\n", log->info("%s Retx PDU scheduled for tx. SN: %d, retx count: %d\n",
rb_id_text[lcid], retx.sn, tx_window[retx.sn].retx_count); rrc->get_rb_name(lcid).c_str(), retx.sn, tx_window[retx.sn].retx_count);
debug_state(); debug_state();
return (ptr-payload) + tx_window[retx.sn].buf->N_bytes; return (ptr-payload) + tx_window[retx.sn].buf->N_bytes;
@ -495,7 +495,7 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r
if(nof_bytes <= head_len) if(nof_bytes <= head_len)
{ {
log->warning("%s Cannot build a PDU segment - %d bytes available, %d bytes required for header\n", log->warning("%s Cannot build a PDU segment - %d bytes available, %d bytes required for header\n",
rb_id_text[lcid], nof_bytes, head_len); rrc->get_rb_name(lcid).c_str(), nof_bytes, head_len);
return 0; return 0;
} }
pdu_space = nof_bytes-head_len; pdu_space = nof_bytes-head_len;
@ -561,15 +561,15 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r
memcpy(ptr, data, len); memcpy(ptr, data, len);
log->info("%s Retx PDU segment scheduled for tx. SN: %d, SO: %d\n", log->info("%s Retx PDU segment scheduled for tx. SN: %d, SO: %d\n",
rb_id_text[lcid], retx.sn, retx.so_start); rrc->get_rb_name(lcid).c_str(), retx.sn, retx.so_start);
debug_state(); debug_state();
int pdu_len = (ptr-payload) + len; int pdu_len = (ptr-payload) + len;
if(pdu_len > (int)nof_bytes) { if(pdu_len > (int)nof_bytes) {
log->error("%s Retx PDU segment length error. Available: %d, Used: %d\n", log->error("%s Retx PDU segment length error. Available: %d, Used: %d\n",
rb_id_text[lcid], nof_bytes, pdu_len); rrc->get_rb_name(lcid).c_str(), nof_bytes, pdu_len);
log->debug("%s Retx PDU segment length error. Header len: %d, Payload len: %d, N_li: %d\n", log->debug("%s Retx PDU segment length error. Header len: %d, Payload len: %d, N_li: %d\n",
rb_id_text[lcid], (ptr-payload), len, new_header.N_li); rrc->get_rb_name(lcid).c_str(), (ptr-payload), len, new_header.N_li);
} }
return pdu_len; return pdu_len;
@ -617,13 +617,13 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
if(pdu_space <= head_len) if(pdu_space <= head_len)
{ {
log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n", log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n",
rb_id_text[lcid], nof_bytes, head_len); rrc->get_rb_name(lcid).c_str(), nof_bytes, head_len);
pool->deallocate(pdu); pool->deallocate(pdu);
return 0; return 0;
} }
log->debug("%s Building PDU - pdu_space: %d, head_len: %d \n", log->debug("%s Building PDU - pdu_space: %d, head_len: %d \n",
rb_id_text[lcid], pdu_space, head_len); rrc->get_rb_name(lcid).c_str(), pdu_space, head_len);
// Check for SDU segment // Check for SDU segment
if(tx_sdu) if(tx_sdu)
@ -638,7 +638,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rb_id_text[lcid], tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;
} }
@ -649,7 +649,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
header.fi |= RLC_FI_FIELD_NOT_START_ALIGNED; // First byte does not correspond to first byte of SDU header.fi |= RLC_FI_FIELD_NOT_START_ALIGNED; // First byte does not correspond to first byte of SDU
log->debug("%s Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d \n", log->debug("%s Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d \n",
rb_id_text[lcid], to_move, pdu_space, head_len); rrc->get_rb_name(lcid).c_str(), to_move, pdu_space, head_len);
} }
// Pull SDUs from queue // Pull SDUs from queue
@ -673,7 +673,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rb_id_text[lcid], tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;
} }
@ -683,7 +683,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
pdu_space = 0; pdu_space = 0;
log->debug("%s Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d \n", log->debug("%s Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d \n",
rb_id_text[lcid], to_move, pdu_space, head_len); rrc->get_rb_name(lcid).c_str(), to_move, pdu_space, head_len);
} }
if(tx_sdu) if(tx_sdu)
@ -692,11 +692,11 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
// Set Poll bit // Set Poll bit
pdu_without_poll++; pdu_without_poll++;
byte_without_poll += (pdu->N_bytes + head_len); byte_without_poll += (pdu->N_bytes + head_len);
log->debug("%s pdu_without_poll: %d\n", rb_id_text[lcid], pdu_without_poll); log->debug("%s pdu_without_poll: %d\n", rrc->get_rb_name(lcid).c_str(), pdu_without_poll);
log->debug("%s byte_without_poll: %d\n", rb_id_text[lcid], byte_without_poll); log->debug("%s byte_without_poll: %d\n", rrc->get_rb_name(lcid).c_str(), byte_without_poll);
if(poll_required()) if(poll_required())
{ {
log->debug("%s setting poll bit to request status\n", rb_id_text[lcid]); log->debug("%s setting poll bit to request status\n", rrc->get_rb_name(lcid).c_str());
header.p = 1; header.p = 1;
poll_sn = vt_s; poll_sn = vt_s;
pdu_without_poll = 0; pdu_without_poll = 0;
@ -707,7 +707,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
// Set SN // Set SN
header.sn = vt_s; header.sn = vt_s;
vt_s = (vt_s + 1)%MOD; vt_s = (vt_s + 1)%MOD;
log->info("%s PDU scheduled for tx. SN: %d\n", rb_id_text[lcid], header.sn); log->info("%s PDU scheduled for tx. SN: %d\n", rrc->get_rb_name(lcid).c_str(), header.sn);
// Place PDU in tx_window, write header and TX // Place PDU in tx_window, write header and TX
tx_window[header.sn].buf = pdu; tx_window[header.sn].buf = pdu;
@ -728,26 +728,26 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h
std::map<uint32_t, rlc_amd_rx_pdu_t>::iterator it; std::map<uint32_t, rlc_amd_rx_pdu_t>::iterator it;
log->info_hex(payload, nof_bytes, "%s Rx data PDU SN: %d", log->info_hex(payload, nof_bytes, "%s Rx data PDU SN: %d",
rb_id_text[lcid], header.sn); rrc->get_rb_name(lcid).c_str(), header.sn);
if(!inside_rx_window(header.sn)) { if(!inside_rx_window(header.sn)) {
if(header.p) { if(header.p) {
log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str());
do_status = true; do_status = true;
} }
log->info("%s SN: %d outside rx window [%d:%d] - discarding\n", log->info("%s SN: %d outside rx window [%d:%d] - discarding\n",
rb_id_text[lcid], header.sn, vr_r, vr_mr); rrc->get_rb_name(lcid).c_str(), header.sn, vr_r, vr_mr);
return; return;
} }
it = rx_window.find(header.sn); it = rx_window.find(header.sn);
if(rx_window.end() != it) { if(rx_window.end() != it) {
if(header.p) { if(header.p) {
log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str());
do_status = true; do_status = true;
} }
log->info("%s Discarding duplicate SN: %d\n", log->info("%s Discarding duplicate SN: %d\n",
rb_id_text[lcid], header.sn); rrc->get_rb_name(lcid).c_str(), header.sn);
return; return;
} }
@ -780,7 +780,7 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h
// Check poll bit // Check poll bit
if(header.p) if(header.p)
{ {
log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str());
poll_received = true; poll_received = true;
// 36.322 v10 Section 5.2.3 // 36.322 v10 Section 5.2.3
@ -825,16 +825,16 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a
std::map<uint32_t, rlc_amd_rx_pdu_segments_t>::iterator it; std::map<uint32_t, rlc_amd_rx_pdu_segments_t>::iterator it;
log->info_hex(payload, nof_bytes, "%s Rx data PDU segment. SN: %d, SO: %d", log->info_hex(payload, nof_bytes, "%s Rx data PDU segment. SN: %d, SO: %d",
rb_id_text[lcid], header.sn, header.so); rrc->get_rb_name(lcid).c_str(), header.sn, header.so);
// Check inside rx window // Check inside rx window
if(!inside_rx_window(header.sn)) { if(!inside_rx_window(header.sn)) {
if(header.p) { if(header.p) {
log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str());
do_status = true; do_status = true;
} }
log->info("%s SN: %d outside rx window [%d:%d] - discarding\n", log->info("%s SN: %d outside rx window [%d:%d] - discarding\n",
rb_id_text[lcid], header.sn, vr_r, vr_mr); rrc->get_rb_name(lcid).c_str(), header.sn, vr_r, vr_mr);
return; return;
} }
@ -853,7 +853,7 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a
if(rx_segments.end() != it) { if(rx_segments.end() != it) {
if(header.p) { if(header.p) {
log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str());
do_status = true; do_status = true;
} }
@ -883,7 +883,7 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a
// Check poll bit // Check poll bit
if(header.p) if(header.p)
{ {
log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str());
poll_received = true; poll_received = true;
// 36.322 v10 Section 5.2.3 // 36.322 v10 Section 5.2.3
@ -901,12 +901,12 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a
void rlc_am::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes) void rlc_am::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes)
{ {
log->info_hex(payload, nof_bytes, "%s Rx control PDU", rb_id_text[lcid]); log->info_hex(payload, nof_bytes, "%s Rx control PDU", rrc->get_rb_name(lcid).c_str());
rlc_status_pdu_t status; rlc_status_pdu_t status;
rlc_am_read_status_pdu(payload, nof_bytes, &status); rlc_am_read_status_pdu(payload, nof_bytes, &status);
log->info("%s Rx Status PDU: %s\n", rb_id_text[lcid], rlc_am_to_string(&status).c_str()); log->info("%s Rx Status PDU: %s\n", rrc->get_rb_name(lcid).c_str(), rlc_am_to_string(&status).c_str());
poll_retx_timeout.reset(); poll_retx_timeout.reset();
@ -944,7 +944,7 @@ void rlc_am::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes)
} }
} else { } else {
log->warning("%s invalid segment NACK received for SN %d. so_start: %d, so_end: %d, N_bytes: %d\n", log->warning("%s invalid segment NACK received for SN %d. so_start: %d, so_end: %d, N_bytes: %d\n",
rb_id_text[lcid], i, status.nacks[j].so_start, status.nacks[j].so_end, it->second.buf->N_bytes); rrc->get_rb_name(lcid).c_str(), i, status.nacks[j].so_start, status.nacks[j].so_end, it->second.buf->N_bytes);
} }
} }
@ -998,7 +998,7 @@ void rlc_am::reassemble_rx_sdus()
rx_sdu->N_bytes += len; rx_sdu->N_bytes += len;
rx_window[vr_r].buf->msg += len; rx_window[vr_r].buf->msg += len;
rx_window[vr_r].buf->N_bytes -= len; rx_window[vr_r].buf->N_bytes -= len;
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU", rb_id_text[lcid]); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU", rrc->get_rb_name(lcid).c_str());
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
pdcp->write_pdu(lcid, rx_sdu); pdcp->write_pdu(lcid, rx_sdu);
rx_sdu = pool_allocate; rx_sdu = pool_allocate;
@ -1014,7 +1014,7 @@ void rlc_am::reassemble_rx_sdus()
rx_sdu->N_bytes += rx_window[vr_r].buf->N_bytes; rx_sdu->N_bytes += rx_window[vr_r].buf->N_bytes;
if(rlc_am_end_aligned(rx_window[vr_r].header.fi)) if(rlc_am_end_aligned(rx_window[vr_r].header.fi))
{ {
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU", rb_id_text[lcid]); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU", rrc->get_rb_name(lcid).c_str());
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
pdcp->write_pdu(lcid, rx_sdu); pdcp->write_pdu(lcid, rx_sdu);
rx_sdu = pool_allocate; rx_sdu = pool_allocate;
@ -1058,7 +1058,7 @@ void rlc_am::debug_state()
{ {
log->debug("%s vt_a = %d, vt_ms = %d, vt_s = %d, poll_sn = %d " log->debug("%s vt_a = %d, vt_ms = %d, vt_s = %d, poll_sn = %d "
"vr_r = %d, vr_mr = %d, vr_x = %d, vr_ms = %d, vr_h = %d\n", "vr_r = %d, vr_mr = %d, vr_x = %d, vr_ms = %d, vr_h = %d\n",
rb_id_text[lcid], vt_a, vt_ms, vt_s, poll_sn, rrc->get_rb_name(lcid).c_str(), vt_a, vt_ms, vt_s, poll_sn,
vr_r, vr_mr, vr_x, vr_ms, vr_h); vr_r, vr_mr, vr_x, vr_ms, vr_h);
} }

@ -79,7 +79,7 @@ uint32_t rlc_tm::get_bearer()
// PDCP interface // PDCP interface
void rlc_tm::write_sdu(byte_buffer_t *sdu) void rlc_tm::write_sdu(byte_buffer_t *sdu)
{ {
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rb_id_text[lcid]); log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rrc->get_rb_name(lcid).c_str());
ul_queue.write(sdu); ul_queue.write(sdu);
} }
@ -99,7 +99,7 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes)
uint32_t pdu_size = ul_queue.size_tail_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", rb_id_text[lcid]); log->error("TX %s PDU size larger than MAC opportunity\n", rrc->get_rb_name(lcid).c_str());
return 0; return 0;
} }
byte_buffer_t *buf; byte_buffer_t *buf;
@ -107,9 +107,9 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes)
pdu_size = buf->N_bytes; pdu_size = buf->N_bytes;
memcpy(payload, buf->msg, buf->N_bytes); memcpy(payload, buf->msg, buf->N_bytes);
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rb_id_text[lcid], buf->get_latency_us()); rrc->get_rb_name(lcid).c_str(), buf->get_latency_us());
pool->deallocate(buf); pool->deallocate(buf);
log->info_hex(payload, pdu_size, "TX %s, %s PDU", rb_id_text[lcid], rlc_mode_text[RLC_MODE_TM]); log->info_hex(payload, pdu_size, "TX %s, %s PDU", rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM]);
return pdu_size; return pdu_size;
} }

@ -78,7 +78,7 @@ void rlc_um::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg)
tx_mod = (RLC_UMD_SN_SIZE_5_BITS == tx_sn_field_length) ? 32 : 1024; tx_mod = (RLC_UMD_SN_SIZE_5_BITS == tx_sn_field_length) ? 32 : 1024;
log->info("%s configured in %s mode: " log->info("%s configured in %s mode: "
"t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n", "t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n",
rb_id_text[lcid], liblte_rrc_rlc_mode_text[cnfg->rlc_mode], rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode],
t_reordering, t_reordering,
rlc_umd_sn_size_num[rx_sn_field_length], rlc_umd_sn_size_num[rx_sn_field_length],
rlc_umd_sn_size_num[tx_sn_field_length]); rlc_umd_sn_size_num[tx_sn_field_length]);
@ -87,7 +87,7 @@ void rlc_um::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg)
tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_uni_rlc.sn_field_len; tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_uni_rlc.sn_field_len;
tx_mod = (RLC_UMD_SN_SIZE_5_BITS == tx_sn_field_length) ? 32 : 1024; tx_mod = (RLC_UMD_SN_SIZE_5_BITS == tx_sn_field_length) ? 32 : 1024;
log->info("%s configured in %s mode: tx_sn_field_length=%u bits\n", log->info("%s configured in %s mode: tx_sn_field_length=%u bits\n",
rb_id_text[lcid], liblte_rrc_rlc_mode_text[cnfg->rlc_mode], rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode],
rlc_umd_sn_size_num[tx_sn_field_length]); rlc_umd_sn_size_num[tx_sn_field_length]);
break; break;
case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: case LIBLTE_RRC_RLC_MODE_UM_UNI_DL:
@ -97,7 +97,7 @@ void rlc_um::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg)
rx_mod = (RLC_UMD_SN_SIZE_5_BITS == rx_sn_field_length) ? 32 : 1024; rx_mod = (RLC_UMD_SN_SIZE_5_BITS == rx_sn_field_length) ? 32 : 1024;
log->info("%s configured in %s mode: " log->info("%s configured in %s mode: "
"t_reordering=%d ms, rx_sn_field_length=%u bits\n", "t_reordering=%d ms, rx_sn_field_length=%u bits\n",
rb_id_text[lcid], liblte_rrc_rlc_mode_text[cnfg->rlc_mode], rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode],
liblte_rrc_t_reordering_num[t_reordering], liblte_rrc_t_reordering_num[t_reordering],
rlc_umd_sn_size_num[rx_sn_field_length]); rlc_umd_sn_size_num[rx_sn_field_length]);
break; break;
@ -159,7 +159,7 @@ uint32_t rlc_um::get_bearer()
void rlc_um::write_sdu(byte_buffer_t *sdu) void rlc_um::write_sdu(byte_buffer_t *sdu)
{ {
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rb_id_text[lcid]); log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rrc->get_rb_name(lcid).c_str());
tx_sdu_queue.write(sdu); tx_sdu_queue.write(sdu);
} }
@ -222,7 +222,7 @@ void rlc_um::timer_expired(uint32_t timeout_id)
// 36.322 v10 Section 5.1.2.2.4 // 36.322 v10 Section 5.1.2.2.4
log->info("%s reordering timeout expiry - updating vr_ur and reassembling\n", log->info("%s reordering timeout expiry - updating vr_ur and reassembling\n",
rb_id_text[lcid]); rrc->get_rb_name(lcid).c_str());
log->warning("Lost PDU SN: %d\n", vr_ur); log->warning("Lost PDU SN: %d\n", vr_ur);
pdu_lost = true; pdu_lost = true;
@ -286,7 +286,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
if(pdu_space <= head_len) if(pdu_space <= head_len)
{ {
log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n", log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n",
rb_id_text[lcid], nof_bytes, head_len); rrc->get_rb_name(lcid).c_str(), nof_bytes, head_len);
return 0; return 0;
} }
@ -296,7 +296,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
uint32_t space = pdu_space-head_len; uint32_t space = pdu_space-head_len;
to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space; to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space;
log->debug("%s adding remainder of SDU segment - %d bytes of %d remaining\n", log->debug("%s adding remainder of SDU segment - %d bytes of %d remaining\n",
rb_id_text[lcid], to_move, tx_sdu->N_bytes); rrc->get_rb_name(lcid).c_str(), to_move, tx_sdu->N_bytes);
memcpy(pdu_ptr, tx_sdu->msg, to_move); memcpy(pdu_ptr, tx_sdu->msg, to_move);
last_li = to_move; last_li = to_move;
pdu_ptr += to_move; pdu_ptr += to_move;
@ -306,7 +306,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rb_id_text[lcid], tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;
} }
@ -325,7 +325,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
uint32_t space = pdu_space-head_len; uint32_t space = pdu_space-head_len;
to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space; to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space;
log->debug("%s adding new SDU segment - %d bytes of %d remaining\n", log->debug("%s adding new SDU segment - %d bytes of %d remaining\n",
rb_id_text[lcid], to_move, tx_sdu->N_bytes); rrc->get_rb_name(lcid).c_str(), to_move, tx_sdu->N_bytes);
memcpy(pdu_ptr, tx_sdu->msg, to_move); memcpy(pdu_ptr, tx_sdu->msg, to_move);
last_li = to_move; last_li = to_move;
pdu_ptr += to_move; pdu_ptr += to_move;
@ -335,7 +335,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
if(tx_sdu->N_bytes == 0) if(tx_sdu->N_bytes == 0)
{ {
log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rb_id_text[lcid], tx_sdu->get_latency_us()); rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); pool->deallocate(tx_sdu);
tx_sdu = NULL; tx_sdu = NULL;
} }
@ -350,11 +350,11 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
vt_us = (vt_us + 1)%tx_mod; vt_us = (vt_us + 1)%tx_mod;
// Add header and TX // Add header and TX
log->debug("%s packing PDU with length %d\n", rb_id_text[lcid], pdu->N_bytes); log->debug("%s packing PDU with length %d\n", rrc->get_rb_name(lcid).c_str(), pdu->N_bytes);
rlc_um_write_data_pdu_header(&header, pdu); rlc_um_write_data_pdu_header(&header, pdu);
memcpy(payload, pdu->msg, pdu->N_bytes); memcpy(payload, pdu->msg, pdu->N_bytes);
uint32_t ret = pdu->N_bytes; uint32_t ret = pdu->N_bytes;
log->debug("%sreturning length %d\n", rb_id_text[lcid], pdu->N_bytes); log->debug("%sreturning length %d\n", rrc->get_rb_name(lcid).c_str(), pdu->N_bytes);
pool->deallocate(pdu); pool->deallocate(pdu);
debug_state(); debug_state();
@ -368,20 +368,20 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
rlc_um_read_data_pdu_header(payload, nof_bytes, rx_sn_field_length, &header); rlc_um_read_data_pdu_header(payload, nof_bytes, rx_sn_field_length, &header);
log->info_hex(payload, nof_bytes, "RX %s Rx data PDU SN: %d", log->info_hex(payload, nof_bytes, "RX %s Rx data PDU SN: %d",
rb_id_text[lcid], header.sn); rrc->get_rb_name(lcid).c_str(), header.sn);
if(RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_uh-rx_window_size) && if(RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_uh-rx_window_size) &&
RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ur)) RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ur))
{ {
log->info("%s SN: %d outside rx window [%d:%d] - discarding\n", log->info("%s SN: %d outside rx window [%d:%d] - discarding\n",
rb_id_text[lcid], header.sn, vr_ur, vr_uh); rrc->get_rb_name(lcid).c_str(), header.sn, vr_ur, vr_uh);
return; return;
} }
it = rx_window.find(header.sn); it = rx_window.find(header.sn);
if(rx_window.end() != it) if(rx_window.end() != it)
{ {
log->info("%s Discarding duplicate SN: %d\n", log->info("%s Discarding duplicate SN: %d\n",
rb_id_text[lcid], header.sn); rrc->get_rb_name(lcid).c_str(), header.sn);
return; return;
} }
@ -456,7 +456,7 @@ void rlc_um::reassemble_rx_sdus()
log->warning("Dropping remainder of lost PDU (lower edge middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu); log->warning("Dropping remainder of lost PDU (lower edge middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu);
rx_sdu->reset(); rx_sdu->reset();
} else { } else {
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", rb_id_text[lcid], vr_ur, i); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", rrc->get_rb_name(lcid).c_str(), vr_ur, i);
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
pdcp->write_pdu(lcid, rx_sdu); pdcp->write_pdu(lcid, rx_sdu);
rx_sdu = pool_allocate; rx_sdu = pool_allocate;
@ -476,7 +476,7 @@ void rlc_um::reassemble_rx_sdus()
log->warning("Dropping remainder of lost PDU (lower edge last segments)\n"); log->warning("Dropping remainder of lost PDU (lower edge last segments)\n");
rx_sdu->reset(); rx_sdu->reset();
} else { } else {
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", rb_id_text[lcid], vr_ur); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", rrc->get_rb_name(lcid).c_str(), vr_ur);
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
pdcp->write_pdu(lcid, rx_sdu); pdcp->write_pdu(lcid, rx_sdu);
rx_sdu = pool_allocate; rx_sdu = pool_allocate;
@ -510,7 +510,7 @@ void rlc_um::reassemble_rx_sdus()
log->warning("Dropping remainder of lost PDU (update vr_ur middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu); log->warning("Dropping remainder of lost PDU (update vr_ur middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu);
rx_sdu->reset(); rx_sdu->reset();
} else { } else {
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", rb_id_text[lcid], vr_ur, i); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", rrc->get_rb_name(lcid).c_str(), vr_ur, i);
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
pdcp->write_pdu(lcid, rx_sdu); pdcp->write_pdu(lcid, rx_sdu);
rx_sdu = pool_allocate; rx_sdu = pool_allocate;
@ -530,7 +530,7 @@ void rlc_um::reassemble_rx_sdus()
log->warning("Dropping remainder of lost PDU (update vr_ur last segments)\n"); log->warning("Dropping remainder of lost PDU (update vr_ur last segments)\n");
rx_sdu->reset(); rx_sdu->reset();
} else { } else {
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", rb_id_text[lcid], vr_ur); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", rrc->get_rb_name(lcid).c_str(), vr_ur);
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
pdcp->write_pdu(lcid, rx_sdu); pdcp->write_pdu(lcid, rx_sdu);
rx_sdu = pool_allocate; rx_sdu = pool_allocate;
@ -560,7 +560,7 @@ bool rlc_um::inside_reordering_window(uint16_t sn)
void rlc_um::debug_state() void rlc_um::debug_state()
{ {
log->debug("%s vt_us = %d, vr_ur = %d, vr_ux = %d, vr_uh = %d \n", log->debug("%s vt_us = %d, vr_ur = %d, vr_ux = %d, vr_uh = %d \n",
rb_id_text[lcid], vt_us, vr_ur, vr_ux, vr_uh); rrc->get_rb_name(lcid).c_str(), vt_us, vr_ur, vr_ux, vr_uh);
} }

@ -67,6 +67,7 @@ public:
// RRC interface // RRC interface
void max_retx_attempted(){} void max_retx_attempted(){}
std::string get_rb_name(uint32_t lcid) { return std::string(""); }
byte_buffer_t *sdus[10]; byte_buffer_t *sdus[10];
int n_sdus; int n_sdus;

@ -71,6 +71,7 @@ public:
// RRC interface // RRC interface
void max_retx_attempted(){} void max_retx_attempted(){}
std::string get_rb_name(uint32_t lcid) { return std::string(""); }
byte_buffer_t *sdus[5]; byte_buffer_t *sdus[5];
int n_sdus; int n_sdus;

@ -43,6 +43,32 @@ namespace srsenb {
#define SRSENB_N_DRB 8 #define SRSENB_N_DRB 8
#define SRSENB_N_RADIO_BEARERS 11 #define SRSENB_N_RADIO_BEARERS 11
typedef enum{
RB_ID_SRB0 = 0,
RB_ID_SRB1,
RB_ID_SRB2,
RB_ID_DRB1,
RB_ID_DRB2,
RB_ID_DRB3,
RB_ID_DRB4,
RB_ID_DRB5,
RB_ID_DRB6,
RB_ID_DRB7,
RB_ID_DRB8,
RB_ID_N_ITEMS,
}rb_id_t;
static const char rb_id_text[RB_ID_N_ITEMS][20] = { "SRB0",
"SRB1",
"SRB2",
"DRB1",
"DRB2",
"DRB3",
"DRB4",
"DRB5",
"DRB6",
"DRB7",
"DRB8"};
// Cat 3 UE - Max number of DL-SCH transport block bits received within a TTI // Cat 3 UE - Max number of DL-SCH transport block bits received within a TTI
// 3GPP 36.306 Table 4.1.1 // 3GPP 36.306 Table 4.1.1
#define SRSENB_MAX_BUFFER_SIZE_BITS 102048 #define SRSENB_MAX_BUFFER_SIZE_BITS 102048

@ -89,6 +89,7 @@ private:
void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu); void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu);
void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu); void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu);
void write_pdu_pcch(srslte::byte_buffer_t *pdu); void write_pdu_pcch(srslte::byte_buffer_t *pdu);
std::string get_rb_name(uint32_t lcid);
}; };
class user_interface class user_interface

@ -54,6 +54,7 @@ public:
// rlc_interface_pdcp // rlc_interface_pdcp
void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu); void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu);
std::string get_rb_name(uint32_t lcid);
// rlc_interface_mac // rlc_interface_mac
int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t *payload, uint32_t nof_bytes); int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t *payload, uint32_t nof_bytes);
@ -73,6 +74,7 @@ private:
void write_pdu_bcch_dlsch(srslte::byte_buffer_t *sdu); void write_pdu_bcch_dlsch(srslte::byte_buffer_t *sdu);
void write_pdu_pcch(srslte::byte_buffer_t *sdu); void write_pdu_pcch(srslte::byte_buffer_t *sdu);
void max_retx_attempted(); void max_retx_attempted();
std::string get_rb_name(uint32_t lcid);
uint16_t rnti; uint16_t rnti;
srsenb::pdcp_interface_rlc *pdcp; srsenb::pdcp_interface_rlc *pdcp;

@ -25,6 +25,7 @@
*/ */
#include "upper/pdcp.h" #include "upper/pdcp.h"
#include "upper/common_enb.h"
namespace srsenb { namespace srsenb {
@ -50,7 +51,7 @@ void pdcp::add_user(uint16_t rnti)
{ {
if (users.count(rnti) == 0) { if (users.count(rnti) == 0) {
srslte::pdcp *obj = new srslte::pdcp; srslte::pdcp *obj = new srslte::pdcp;
obj->init(&users[rnti].rlc_itf, &users[rnti].rrc_itf, &users[rnti].gtpu_itf, log_h, SECURITY_DIRECTION_DOWNLINK); obj->init(&users[rnti].rlc_itf, &users[rnti].rrc_itf, &users[rnti].gtpu_itf, log_h, RB_ID_SRB0, SECURITY_DIRECTION_DOWNLINK);
users[rnti].rlc_itf.rnti = rnti; users[rnti].rlc_itf.rnti = rnti;
users[rnti].gtpu_itf.rnti = rnti; users[rnti].gtpu_itf.rnti = rnti;
users[rnti].rrc_itf.rnti = rnti; users[rnti].rrc_itf.rnti = rnti;
@ -72,10 +73,16 @@ void pdcp::rem_user(uint16_t rnti)
} }
} }
void pdcp::add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT* cnfg) void pdcp::add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT* cnfg_)
{ {
if (users.count(rnti)) { if (users.count(rnti)) {
users[rnti].pdcp->add_bearer(lcid, cnfg); srslte::srslte_pdcp_config_t cfg;
if(cnfg_->rlc_um_pdcp_sn_size_present) {
if(LIBLTE_RRC_PDCP_SN_SIZE_7_BITS == cnfg_->rlc_um_pdcp_sn_size) {
cfg.sn_len = 7;
}
}
users[rnti].pdcp->add_bearer(lcid, cfg);
} }
} }
@ -143,6 +150,10 @@ void pdcp::user_interface_rrc::write_pdu_pcch(srslte::byte_buffer_t* pdu)
{ {
fprintf(stderr, "Error: Received PCCH from ue=%d\n", rnti); fprintf(stderr, "Error: Received PCCH from ue=%d\n", rnti);
} }
std::string pdcp::user_interface_rrc::get_rb_name(uint32_t lcid)
{
return std::string(rb_id_text[lcid]);
}
} }

@ -25,6 +25,7 @@
*/ */
#include "upper/rlc.h" #include "upper/rlc.h"
#include "upper/common_enb.h"
namespace srsenb { namespace srsenb {
@ -53,7 +54,7 @@ void rlc::add_user(uint16_t rnti)
{ {
if (users.count(rnti) == 0) { if (users.count(rnti) == 0) {
srslte::rlc *obj = new srslte::rlc; srslte::rlc *obj = new srslte::rlc;
obj->init(&users[rnti], &users[rnti], &users[rnti], log_h, mac_timers); obj->init(&users[rnti], &users[rnti], &users[rnti], log_h, mac_timers, RB_ID_SRB0);
users[rnti].rnti = rnti; users[rnti].rnti = rnti;
users[rnti].pdcp = pdcp; users[rnti].pdcp = pdcp;
users[rnti].rrc = rrc; users[rnti].rrc = rrc;
@ -184,4 +185,9 @@ void rlc::user_interface::write_pdu_pcch(srslte::byte_buffer_t* sdu)
fprintf(stderr, "Error: Received PCCH from ue=%d\n", rnti); fprintf(stderr, "Error: Received PCCH from ue=%d\n", rnti);
} }
std::string rlc::user_interface::get_rb_name(uint32_t lcid)
{
return std::string(rb_id_text[lcid]);
}
} }

@ -27,10 +27,8 @@
#include "srslte/asn1/liblte_mme.h" #include "srslte/asn1/liblte_mme.h"
#include "upper/rrc.h" #include "upper/rrc.h"
using srslte::rb_id_text;
using srslte::byte_buffer_t; using srslte::byte_buffer_t;
using srslte::bit_buffer_t; using srslte::bit_buffer_t;
using srslte::rb_id_t;
namespace srsenb { namespace srsenb {
@ -607,11 +605,11 @@ void rrc::run_thread()
} }
switch(p.lcid) switch(p.lcid)
{ {
case srslte::RB_ID_SRB0: case RB_ID_SRB0:
parse_ul_ccch(p.rnti, p.pdu); parse_ul_ccch(p.rnti, p.pdu);
break; break;
case srslte::RB_ID_SRB1: case RB_ID_SRB1:
case srslte::RB_ID_SRB2: case RB_ID_SRB2:
parse_ul_dcch(p.rnti, p.lcid, p.pdu); parse_ul_dcch(p.rnti, p.lcid, p.pdu);
break; break;
case LCID_REM_USER: case LCID_REM_USER:
@ -919,7 +917,7 @@ void rrc::ue::set_security_key(uint8_t* key, uint32_t length)
k_up_enc, k_up_enc,
k_up_int); k_up_int);
parent->configure_security(rnti, srslte::RB_ID_SRB1, parent->configure_security(rnti, RB_ID_SRB1,
k_rrc_enc, k_rrc_int, k_rrc_enc, k_rrc_int,
k_up_enc, k_up_int, k_up_enc, k_up_int,
cipher_algo, integ_algo); cipher_algo, integ_algo);
@ -1432,7 +1430,7 @@ void rrc::ue::send_dl_ccch(LIBLTE_RRC_DL_CCCH_MSG_STRUCT *dl_ccch_msg)
rnti, rnti,
liblte_rrc_dl_ccch_msg_type_text[dl_ccch_msg->msg_type]); liblte_rrc_dl_ccch_msg_type_text[dl_ccch_msg->msg_type]);
parent->pdcp->write_sdu(rnti, srslte::RB_ID_SRB0, pdu); parent->pdcp->write_sdu(rnti, RB_ID_SRB0, pdu);
} else { } else {
parent->rrc_log->error("Allocating pdu\n"); parent->rrc_log->error("Allocating pdu\n");
@ -1453,7 +1451,7 @@ void rrc::ue::send_dl_dcch(LIBLTE_RRC_DL_DCCH_MSG_STRUCT *dl_dcch_msg, byte_buff
rnti, rnti,
liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg->msg_type]); liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg->msg_type]);
parent->pdcp->write_sdu(rnti, srslte::RB_ID_SRB1, pdu); parent->pdcp->write_sdu(rnti, RB_ID_SRB1, pdu);
} else { } else {
parent->rrc_log->error("Allocating pdu\n"); parent->rrc_log->error("Allocating pdu\n");

@ -155,6 +155,7 @@ public:
void set_activity_user(uint16_t rnti) {} void set_activity_user(uint16_t rnti) {}
bool is_paging_opportunity(uint32_t tti, uint32_t *payload_len) {return false;} bool is_paging_opportunity(uint32_t tti, uint32_t *payload_len) {return false;}
void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) {} void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) {}
std::string get_rb_name(uint32_t lcid) { return std::string("lcid"); }
void write_pdu(uint32_t lcid, srslte::byte_buffer_t *sdu) void write_pdu(uint32_t lcid, srslte::byte_buffer_t *sdu)
{ {
@ -566,7 +567,7 @@ int main(int argc, char *argv[])
my_phy.init(&phy_args, &phy_cfg, &my_radio, &my_mac, &log_phy); my_phy.init(&phy_args, &phy_cfg, &my_radio, &my_mac, &log_phy);
my_mac.init(&mac_args, &mac_cfg.cell, &my_phy, &my_tester, &my_tester, &log_mac); my_mac.init(&mac_args, &mac_cfg.cell, &my_phy, &my_tester, &my_tester, &log_mac);
my_rlc.init(&my_tester, &my_tester, &my_tester, &log_rlc, &my_mac); my_rlc.init(&my_tester, &my_tester, &my_tester, &log_rlc, &my_mac, 0 /* SRB0 */);
my_tester.init(&my_rlc, &my_mac, &my_phy, &log_tester, prog_args.ip_address); my_tester.init(&my_rlc, &my_mac, &my_phy, &log_tester, prog_args.ip_address);
if (prog_args.enable_gui) { if (prog_args.enable_gui) {

@ -65,7 +65,8 @@ public:
void init(usim_interface_nas *usim_, void init(usim_interface_nas *usim_,
rrc_interface_nas *rrc_, rrc_interface_nas *rrc_,
gw_interface_nas *gw_, gw_interface_nas *gw_,
srslte::log *nas_log_); srslte::log *nas_log_,
uint32_t lcid_);
void stop(); void stop();
emm_state_t get_state(); emm_state_t get_state();
@ -83,6 +84,7 @@ private:
rrc_interface_nas *rrc; rrc_interface_nas *rrc;
usim_interface_nas *usim; usim_interface_nas *usim;
gw_interface_nas *gw; gw_interface_nas *gw;
uint32_t default_lcid;
emm_state_t state; emm_state_t state;

@ -144,6 +144,23 @@ private:
void write_pdu_bcch_dlsch(byte_buffer_t *pdu); void write_pdu_bcch_dlsch(byte_buffer_t *pdu);
void write_pdu_pcch(byte_buffer_t *pdu); void write_pdu_pcch(byte_buffer_t *pdu);
// Radio bearers
typedef enum{
RB_ID_SRB0 = 0,
RB_ID_SRB1,
RB_ID_SRB2,
RB_ID_DRB1,
RB_ID_DRB2,
RB_ID_DRB3,
RB_ID_DRB4,
RB_ID_DRB5,
RB_ID_DRB6,
RB_ID_DRB7,
RB_ID_DRB8
} rb_id_t;
std::map<uint8_t, std::string> bearers;
std::string get_rb_name(uint32_t lcid) { return bearers.at(lcid); }
// RLC interface // RLC interface
void max_retx_attempted(); void max_retx_attempted();
@ -185,6 +202,7 @@ private:
void set_phy_default(); void set_phy_default();
void set_mac_default(); void set_mac_default();
void set_rrc_default(); void set_rrc_default();
void set_bearers();
}; };

@ -161,14 +161,15 @@ bool ue::init(all_args_t *args_)
phy_log.console("Setting frequency: DL=%.1f Mhz, UL=%.1f MHz\n", args->rf.dl_freq/1e6, args->rf.ul_freq/1e6); phy_log.console("Setting frequency: DL=%.1f Mhz, UL=%.1f MHz\n", args->rf.dl_freq/1e6, args->rf.ul_freq/1e6);
mac.init(&phy, &rlc, &rrc, &mac_log); mac.init(&phy, &rlc, &rrc, &mac_log);
rlc.init(&pdcp, &rrc, this, &rlc_log, &mac); rlc.init(&pdcp, &rrc, this, &rlc_log, &mac, 0 /* RB_ID_SRB0 */);
pdcp.init(&rlc, &rrc, &gw, &pdcp_log, SECURITY_DIRECTION_UPLINK);
pdcp.init(&rlc, &rrc, &gw, &pdcp_log, 0 /* RB_ID_SRB0 */, SECURITY_DIRECTION_UPLINK);
rrc.init(&phy, &mac, &rlc, &pdcp, &nas, &usim, &mac, &rrc_log); rrc.init(&phy, &mac, &rlc, &pdcp, &nas, &usim, &mac, &rrc_log);
rrc.set_ue_category(atoi(args->expert.ue_cateogry.c_str())); rrc.set_ue_category(atoi(args->expert.ue_cateogry.c_str()));
nas.init(&usim, &rrc, &gw, &nas_log); nas.init(&usim, &rrc, &gw, &nas_log, 1 /* RB_ID_SRB1 */);
gw.init(&pdcp, &rrc, this, &gw_log); gw.init(&pdcp, &rrc, this, &gw_log, 3 /* RB_ID_DRB1 */);
usim.init(&args->usim, &usim_log); usim.init(&args->usim, &usim_log);
started = true; started = true;

@ -43,13 +43,15 @@ nas::nas()
void nas::init(usim_interface_nas *usim_, void nas::init(usim_interface_nas *usim_,
rrc_interface_nas *rrc_, rrc_interface_nas *rrc_,
gw_interface_nas *gw_, gw_interface_nas *gw_,
srslte::log *nas_log_) srslte::log *nas_log_,
uint32_t lcid_)
{ {
pool = byte_buffer_pool::get_instance(); pool = byte_buffer_pool::get_instance();
usim = usim_; usim = usim_;
rrc = rrc_; rrc = rrc_;
gw = gw_; gw = gw_;
nas_log = nas_log_; nas_log = nas_log_;
default_lcid = lcid_;
} }
void nas::stop() void nas::stop()
@ -85,7 +87,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu)
uint8 pd; uint8 pd;
uint8 msg_type; uint8 msg_type;
nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rb_id_text[lcid]); nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str());
// Parse the message // Parse the message
liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)pdu, &pd, &msg_type); liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)pdu, &pd, &msg_type);
@ -492,8 +494,8 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
pdu->N_bytes-5, pdu->N_bytes-5,
&pdu->msg[1]); &pdu->msg[1]);
nas_log->info("Sending Security Mode Complete nas_count_ul=%d, RB=%s\n", nas_log->info("Sending Security Mode Complete nas_count_ul=%d, RB=%s\n",
count_ul, count_ul,
rb_id_text[lcid]); rrc->get_rb_name(lcid).c_str());
success = true; success = true;
} }
} }
@ -572,7 +574,7 @@ void nas::send_attach_request()
liblte_mme_pack_attach_request_msg(&attach_req, (LIBLTE_BYTE_MSG_STRUCT*)msg); liblte_mme_pack_attach_request_msg(&attach_req, (LIBLTE_BYTE_MSG_STRUCT*)msg);
nas_log->info("Sending attach request\n"); nas_log->info("Sending attach request\n");
rrc->write_sdu(RB_ID_SRB1, msg); rrc->write_sdu(default_lcid, msg);
} }
void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg)
@ -614,7 +616,7 @@ void nas::send_service_request()
uint8_t mac[4]; uint8_t mac[4];
integrity_generate(&k_nas_int[16], integrity_generate(&k_nas_int[16],
count_ul, count_ul,
RB_ID_SRB1-1, default_lcid-1,
SECURITY_DIRECTION_UPLINK, SECURITY_DIRECTION_UPLINK,
&msg->msg[0], &msg->msg[0],
2, 2,
@ -625,7 +627,7 @@ void nas::send_service_request()
msg->msg[3] = mac[3]; msg->msg[3] = mac[3];
msg->N_bytes++; msg->N_bytes++;
nas_log->info("Sending service request\n"); nas_log->info("Sending service request\n");
rrc->write_sdu(RB_ID_SRB1, msg); rrc->write_sdu(default_lcid, msg);
} }
void nas::send_esm_information_response(){} void nas::send_esm_information_response(){}

@ -32,6 +32,7 @@
#include "srslte/phy/utils/bit.h" #include "srslte/phy/utils/bit.h"
#include "srslte/common/security.h" #include "srslte/common/security.h"
#include "srslte/common/bcd_helpers.h" #include "srslte/common/bcd_helpers.h"
#include "boost/assign.hpp"
#define TIMEOUT_RESYNC_REESTABLISH 100 #define TIMEOUT_RESYNC_REESTABLISH 100
@ -42,7 +43,9 @@ namespace srsue{
rrc::rrc() rrc::rrc()
:state(RRC_STATE_IDLE) :state(RRC_STATE_IDLE)
,drb_up(false) ,drb_up(false)
{} {
set_bearers();
}
static void liblte_rrc_handler(void *ctx, char *str) { static void liblte_rrc_handler(void *ctx, char *str) {
rrc *r = (rrc*) ctx; rrc *r = (rrc*) ctx;
@ -116,7 +119,7 @@ void rrc::set_ue_category(int category)
void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu)
{ {
rrc_log->info_hex(sdu->msg, sdu->N_bytes, "RX %s SDU", rb_id_text[lcid]); rrc_log->info_hex(sdu->msg, sdu->N_bytes, "RX %s SDU", bearers.at(lcid));
switch(state) switch(state)
{ {
@ -227,7 +230,7 @@ bool rrc::have_drb()
void rrc::write_pdu(uint32_t lcid, byte_buffer_t *pdu) void rrc::write_pdu(uint32_t lcid, byte_buffer_t *pdu)
{ {
rrc_log->info_hex(pdu->msg, pdu->N_bytes, "TX %s PDU", rb_id_text[lcid]); rrc_log->info_hex(pdu->msg, pdu->N_bytes, "TX %s PDU", bearers.at(lcid));
rrc_log->info("TX PDU Stack latency: %ld us\n", pdu->get_latency_us()); rrc_log->info("TX PDU Stack latency: %ld us\n", pdu->get_latency_us());
switch(lcid) switch(lcid)
@ -793,7 +796,7 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu)
liblte_rrc_unpack_dl_dcch_msg((LIBLTE_BIT_MSG_STRUCT*)&bit_buf, &dl_dcch_msg); liblte_rrc_unpack_dl_dcch_msg((LIBLTE_BIT_MSG_STRUCT*)&bit_buf, &dl_dcch_msg);
rrc_log->info("%s - Received %s\n", rrc_log->info("%s - Received %s\n",
rb_id_text[lcid], bearers.at(lcid),
liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg.msg_type]); liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg.msg_type]);
// Reset and reuse pdu buffer if possible // Reset and reuse pdu buffer if possible
@ -1326,9 +1329,10 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGU
void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg) void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg)
{ {
// Setup PDCP // Setup PDCP
pdcp->add_bearer(srb_cnfg->srb_id); pdcp->add_bearer(srb_cnfg->srb_id, srslte_pdcp_config_t(true)); // Set PDCP config control flag
if(RB_ID_SRB2 == srb_cnfg->srb_id) if(RB_ID_SRB2 == srb_cnfg->srb_id) {
pdcp->config_security(srb_cnfg->srb_id, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); pdcp->config_security(srb_cnfg->srb_id, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo);
}
// Setup RLC // Setup RLC
if(srb_cnfg->rlc_cnfg_present) if(srb_cnfg->rlc_cnfg_present)
@ -1372,7 +1376,7 @@ void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg)
} }
srbs[srb_cnfg->srb_id] = *srb_cnfg; srbs[srb_cnfg->srb_id] = *srb_cnfg;
rrc_log->info("Added radio bearer %s\n", rb_id_text[srb_cnfg->srb_id]); rrc_log->info("Added radio bearer %s\n", bearers.at(srb_cnfg->srb_id));
} }
void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg)
@ -1394,7 +1398,14 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg)
} }
// Setup PDCP // Setup PDCP
pdcp->add_bearer(lcid, &drb_cnfg->pdcp_cnfg); srslte_pdcp_config_t pdcp_cfg;
pdcp_cfg.is_data = true;
if (drb_cnfg->pdcp_cnfg.rlc_um_pdcp_sn_size_present) {
if (LIBLTE_RRC_PDCP_SN_SIZE_7_BITS == drb_cnfg->pdcp_cnfg.rlc_um_pdcp_sn_size) {
pdcp_cfg.sn_len = 7;
}
}
pdcp->add_bearer(lcid, pdcp_cfg);
// TODO: setup PDCP security (using k_up_enc) // TODO: setup PDCP security (using k_up_enc)
// Setup RLC // Setup RLC
@ -1426,7 +1437,7 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg)
drbs[lcid] = *drb_cnfg; drbs[lcid] = *drb_cnfg;
drb_up = true; drb_up = true;
rrc_log->info("Added radio bearer %s\n", rb_id_text[lcid]); rrc_log->info("Added radio bearer %s\n", bearers.at(lcid));
} }
void rrc::release_drb(uint8_t lcid) void rrc::release_drb(uint8_t lcid)
@ -1486,4 +1497,19 @@ void rrc::set_rrc_default() {
mac_timers->get(safe_reset_timer)->set(this, 10); mac_timers->get(safe_reset_timer)->set(this, 10);
} }
void rrc::set_bearers()
{
boost::assign::insert(bearers) (RB_ID_SRB0, "SRB0")
(RB_ID_SRB1, "SRB1")
(RB_ID_SRB2, "SRB2")
(RB_ID_DRB1, "DRB1")
(RB_ID_DRB2, "DRB2")
(RB_ID_DRB3, "DRB3")
(RB_ID_DRB4, "DRB4")
(RB_ID_DRB5, "DRB5")
(RB_ID_DRB6, "DRB6")
(RB_ID_DRB7, "DRB7")
(RB_ID_DRB8, "DRB8");
}
} // namespace srsue } // namespace srsue

@ -269,6 +269,7 @@ public:
} }
void write_pdu_pcch(srslte::byte_buffer_t *sdu) {} void write_pdu_pcch(srslte::byte_buffer_t *sdu) {}
void max_retx_attempted(){} void max_retx_attempted(){}
std::string get_rb_name(uint32_t lcid) { return std::string("rb"); }
void in_sync() {}; void in_sync() {};
void out_of_sync() {}; void out_of_sync() {};
@ -543,7 +544,7 @@ int main(int argc, char *argv[])
my_phy.init(&my_radio, &my_mac, &my_tester, &log_phy, NULL); my_phy.init(&my_radio, &my_mac, &my_tester, &log_phy, NULL);
my_mac.init(&my_phy, &rlc, &my_tester, &log_mac); my_mac.init(&my_phy, &rlc, &my_tester, &log_mac);
rlc.init(&my_tester, &my_tester, &my_tester, &log_rlc, &my_mac); rlc.init(&my_tester, &my_tester, &my_tester, &log_rlc, &my_mac, 0 /* SRB0 */);
my_tester.init(&my_phy, &my_mac, &rlc, &log_tester, prog_args.ip_address); my_tester.init(&my_phy, &my_mac, &rlc, &log_tester, prog_args.ip_address);

Loading…
Cancel
Save