refactor RLC to use RAT-agnostic config

master
Andre Puschmann 8 years ago
parent 9398e0eff9
commit 7ca0988ea3

@ -29,6 +29,7 @@
#include "srslte/common/common.h"
#include "srslte/common/security.h"
#include "srslte/interfaces/sched_interface.h"
#include "srslte/upper/rlc_interface.h"
#include "srslte/asn1/liblte_rrc.h"
#include "srslte/asn1/liblte_s1ap.h"
@ -156,7 +157,7 @@ public:
virtual void add_user(uint16_t rnti) = 0;
virtual void rem_user(uint16_t rnti) = 0;
virtual void add_bearer(uint16_t rnti, uint32_t lcid) = 0;
virtual void add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0;
virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_rlc_config_t cnfg) = 0;
};
// PDCP interface for GTPU

@ -39,6 +39,7 @@
#include "srslte/common/interfaces_common.h"
#include "srslte/common/common.h"
#include "srslte/common/security.h"
#include "srslte/upper/rlc_interface.h"
namespace srsue {
@ -201,7 +202,7 @@ class rlc_interface_rrc
public:
virtual void reset() = 0;
virtual void add_bearer(uint32_t lcid) = 0;
virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0;
virtual void add_bearer(uint32_t lcid, srslte::srslte_rlc_config_t cnfg) = 0;
};
// RLC interface for PDCP

@ -34,6 +34,7 @@
#include "srslte/common/msg_queue.h"
#include "srslte/upper/rlc_entity.h"
#include "srslte/upper/rlc_metrics.h"
#include "srslte/upper/rlc_common.h"
namespace srslte {
@ -77,7 +78,7 @@ public:
// RRC interface
void reset();
void add_bearer(uint32_t lcid);
void add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg);
void add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg);
private:
void reset_metrics();

@ -76,7 +76,7 @@ public:
srsue::pdcp_interface_rlc *pdcp_,
srsue::rrc_interface_rlc *rrc_,
mac_interface_timers *mac_timers);
void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg);
void configure(srslte_rlc_config_t cnfg);
void reset();
void empty_queue();
@ -128,15 +128,7 @@ private:
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
***************************************************************************/
// TX configs
int32_t t_poll_retx; // Poll retx timeout (ms)
int32_t poll_pdu; // Insert poll bit after this many PDUs
int32_t poll_byte; // Insert poll bit after this much data (KB)
uint32_t max_retx_thresh; // Max number of retx
// RX configs
int32_t t_reordering; // Timer used by rx to detect PDU loss (ms)
int32_t t_status_prohibit; // Timer used by rx to prohibit tx of status PDU (ms)
srslte_rlc_am_config_t cfg;
/****************************************************************************
* State variables and counters

@ -27,6 +27,8 @@
#ifndef RLC_COMMON_H
#define RLC_COMMON_H
#include "srslte/upper/rlc_interface.h"
namespace srslte {
/****************************************************************************
@ -66,14 +68,6 @@ typedef enum{
static const char rlc_dc_field_text[RLC_DC_FIELD_N_ITEMS][20] = {"Control PDU",
"Data PDU"};
typedef enum{
RLC_UMD_SN_SIZE_5_BITS = 0,
RLC_UMD_SN_SIZE_10_BITS,
RLC_UMD_SN_SIZE_N_ITEMS,
}rlc_umd_sn_size_t;
static const char rlc_umd_sn_size_text[RLC_UMD_SN_SIZE_N_ITEMS][20] = {"5 bits", "10 bits"};
static const uint16_t rlc_umd_sn_size_num[RLC_UMD_SN_SIZE_N_ITEMS] = {5, 10};
// UMD PDU Header
typedef struct{
uint8_t fi; // Framing info
@ -162,7 +156,7 @@ public:
srsue::pdcp_interface_rlc *pdcp_,
srsue::rrc_interface_rlc *rrc_,
srslte::mac_interface_timers *mac_timers_) = 0;
virtual void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0;
virtual void configure(srslte_rlc_config_t cnfg) = 0;
virtual void reset() = 0;
virtual void empty_queue() = 0;

@ -54,7 +54,7 @@ public:
srsue::rrc_interface_rlc *rrc_,
mac_interface_timers *mac_timers_);
void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg);
void configure(srslte_rlc_config_t cnfg);
void reset();
bool active();

@ -0,0 +1,126 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsUE library.
*
* srsUE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsUE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef RLC_INTERFACE_H
#define RLC_INTERFACE_H
// for custom constructors
#include "srslte/asn1/liblte_rrc.h"
namespace srslte {
typedef enum{
RLC_UMD_SN_SIZE_5_BITS = 0,
RLC_UMD_SN_SIZE_10_BITS,
RLC_UMD_SN_SIZE_N_ITEMS,
}rlc_umd_sn_size_t;
static const char rlc_umd_sn_size_text[RLC_UMD_SN_SIZE_N_ITEMS][20] = {"5 bits", "10 bits"};
static const uint16_t rlc_umd_sn_size_num[RLC_UMD_SN_SIZE_N_ITEMS] = {5, 10};
typedef struct {
/****************************************************************************
* Configurable parameters
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
***************************************************************************/
// TX configs
int32_t t_poll_retx; // Poll retx timeout (ms)
int32_t poll_pdu; // Insert poll bit after this many PDUs
int32_t poll_byte; // Insert poll bit after this much data (KB)
uint32_t max_retx_thresh; // Max number of retx
// RX configs
int32_t t_reordering; // Timer used by rx to detect PDU loss (ms)
int32_t t_status_prohibit; // Timer used by rx to prohibit tx of status PDU (ms)
} srslte_rlc_am_config_t;
typedef struct {
/****************************************************************************
* Configurable parameters
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
***************************************************************************/
int32_t t_reordering; // Timer used by rx to detect PDU loss (ms)
rlc_umd_sn_size_t tx_sn_field_length; // Number of bits used for tx (UL) sequence number
rlc_umd_sn_size_t rx_sn_field_length; // Number of bits used for rx (DL) sequence number
uint32_t rx_window_size;
uint32_t rx_mod; // Rx counter modulus
uint32_t tx_mod; // Tx counter modulus
} srslte_rlc_um_config_t;
class srslte_rlc_config_t
{
public:
LIBLTE_RRC_RLC_MODE_ENUM rlc_mode;
srslte_rlc_am_config_t am;
srslte_rlc_um_config_t 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()
{
switch(rlc_mode)
{
case LIBLTE_RRC_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
am.max_retx_thresh = liblte_rrc_max_retx_threshold_num[cnfg->ul_am_rlc.max_retx_thresh];
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:
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;
um.rx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 32 : 1024;
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;
}
}
};
} // namespace srslte
#endif // RLC_INTERFACE_H

@ -46,7 +46,7 @@ public:
srsue::pdcp_interface_rlc *pdcp_,
srsue::rrc_interface_rlc *rrc_,
mac_interface_timers *mac_timers);
void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg);
void configure(srslte_rlc_config_t cnfg);
void reset();
void empty_queue();

@ -56,7 +56,7 @@ public:
srsue::pdcp_interface_rlc *pdcp_,
srsue::rrc_interface_rlc *rrc_,
mac_interface_timers *mac_timers_);
void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg);
void configure(srslte_rlc_config_t cnfg);
void reset();
void empty_queue();
@ -92,9 +92,6 @@ private:
// Rx window
std::map<uint32_t, rlc_umd_pdu_t> rx_window;
uint32_t rx_window_size;
uint32_t rx_mod; // Rx counter modulus
uint32_t tx_mod; // Tx counter modulus
// RX SDU buffers
byte_buffer_t *rx_sdu;
@ -108,9 +105,7 @@ private:
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
***************************************************************************/
int32_t t_reordering; // Timer used by rx to detect PDU loss (ms)
rlc_umd_sn_size_t tx_sn_field_length; // Number of bits used for tx (UL) sequence number
rlc_umd_sn_size_t rx_sn_field_length; // Number of bits used for rx (DL) sequence number
srslte_rlc_um_config_t cfg;
/****************************************************************************
* State variables and counters

@ -194,10 +194,10 @@ void rlc::write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes)
void rlc::add_bearer(uint32_t lcid)
{
// No config provided - use defaults for lcid
LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg;
if(default_lcid == lcid || (default_lcid+1) == lcid)
{
if (!rlc_array[lcid].active()) {
LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg;
cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM;
cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS45;
cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_INFINITY;
@ -205,7 +205,7 @@ void rlc::add_bearer(uint32_t lcid)
cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4;
cnfg.dl_am_rlc.t_reordering = LIBLTE_RRC_T_REORDERING_MS35;
cnfg.dl_am_rlc.t_status_prohibit = LIBLTE_RRC_T_STATUS_PROHIBIT_MS0;
add_bearer(lcid, &cnfg);
add_bearer(lcid, srslte_rlc_config_t(&cnfg));
} else {
rlc_log->warning("Bearer %s already configured. Reconfiguration not supported\n", get_rb_name(lcid).c_str());
}
@ -215,18 +215,17 @@ void rlc::add_bearer(uint32_t lcid)
}
}
void rlc::add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg)
void rlc::add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg)
{
if(lcid < 0 || lcid >= SRSLTE_N_RADIO_BEARERS) {
rlc_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid);
return;
}
if (!rlc_array[lcid].active()) {
rlc_log->info("Adding radio bearer %s with mode %s\n",
get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode]);
switch(cnfg->rlc_mode)
get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg.rlc_mode]);
switch(cnfg.rlc_mode)
{
case LIBLTE_RRC_RLC_MODE_AM:
rlc_array[lcid].init(RLC_MODE_AM, rlc_log, lcid, pdcp, rrc, mac_timers);

@ -74,20 +74,13 @@ void rlc_am::init(srslte::log *log_,
rrc = rrc_;
}
void rlc_am::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg)
void rlc_am::configure(srslte_rlc_config_t cfg_)
{
t_poll_retx = liblte_rrc_t_poll_retransmit_num[cnfg->ul_am_rlc.t_poll_retx];
poll_pdu = liblte_rrc_poll_pdu_num[cnfg->ul_am_rlc.poll_pdu];
poll_byte = liblte_rrc_poll_byte_num[cnfg->ul_am_rlc.poll_byte]*1000; // KB
max_retx_thresh = liblte_rrc_max_retx_threshold_num[cnfg->ul_am_rlc.max_retx_thresh];
t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_am_rlc.t_reordering];
t_status_prohibit = liblte_rrc_t_status_prohibit_num[cnfg->dl_am_rlc.t_status_prohibit];
cfg = cfg_.am;
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",
rrc->get_rb_name(lcid).c_str(), t_poll_retx, poll_pdu, poll_byte, max_retx_thresh,
t_reordering, t_status_prohibit);
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);
}
@ -362,7 +355,7 @@ void rlc_am::check_reordering_timeout()
if(RX_MOD_BASE(vr_h) > RX_MOD_BASE(vr_ms))
{
reordering_timeout.start(t_reordering);
reordering_timeout.start(cfg.t_reordering);
vr_x = vr_h;
}
@ -376,9 +369,9 @@ void rlc_am::check_reordering_timeout()
bool rlc_am::poll_required()
{
if(poll_pdu > 0 && pdu_without_poll > (uint32_t)poll_pdu)
if(cfg.poll_pdu > 0 && pdu_without_poll > (uint32_t)cfg.poll_pdu)
return true;
if(poll_byte > 0 && byte_without_poll > (uint32_t)poll_byte)
if(cfg.poll_byte > 0 && byte_without_poll > (uint32_t)cfg.poll_byte)
return true;
if(poll_retx())
return true;
@ -414,8 +407,8 @@ int rlc_am::build_status_pdu(uint8_t *payload, uint32_t nof_bytes)
do_status = false;
poll_received = false;
if(t_status_prohibit > 0)
status_prohibit_timeout.start(t_status_prohibit);
if(cfg.t_status_prohibit > 0)
status_prohibit_timeout.start(cfg.t_status_prohibit);
debug_state();
return rlc_am_write_status_pdu(&status, payload);
}else{
@ -450,7 +443,7 @@ int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes)
poll_sn = vt_s;
pdu_without_poll = 0;
byte_without_poll = 0;
poll_retx_timeout.start(t_poll_retx);
poll_retx_timeout.start(cfg.t_poll_retx);
}
uint8_t *ptr = payload;
@ -459,7 +452,7 @@ int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes)
retx_queue.pop_front();
tx_window[retx.sn].retx_count++;
if(tx_window[retx.sn].retx_count >= max_retx_thresh)
if(tx_window[retx.sn].retx_count >= cfg.max_retx_thresh)
rrc->max_retx_attempted();
log->info("%s Retx PDU scheduled for tx. SN: %d, retx count: %d\n",
rrc->get_rb_name(lcid).c_str(), retx.sn, tx_window[retx.sn].retx_count);
@ -701,7 +694,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
poll_sn = vt_s;
pdu_without_poll = 0;
byte_without_poll = 0;
poll_retx_timeout.start(t_poll_retx);
poll_retx_timeout.start(cfg.t_poll_retx);
}
// Set SN
@ -812,7 +805,7 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h
{
if(RX_MOD_BASE(vr_h) > RX_MOD_BASE(vr_r))
{
reordering_timeout.start(t_reordering);
reordering_timeout.start(cfg.t_reordering);
vr_x = vr_h;
}
}

@ -64,7 +64,7 @@ void rlc_entity::init(rlc_mode_t mode,
rlc->init(rlc_entity_log_, lcid_, pdcp_, rrc_, mac_timers_);
}
void rlc_entity::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg)
void rlc_entity::configure(srslte_rlc_config_t cnfg)
{
if(rlc)
rlc->configure(cnfg);

@ -46,7 +46,7 @@ void rlc_tm::init(srslte::log *log_,
rrc = rrc_;
}
void rlc_tm::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg)
void rlc_tm::configure(srslte_rlc_config_t cnfg)
{
log->error("Attempted to configure TM RLC entity");
}

@ -27,7 +27,7 @@
#include "srslte/upper/rlc_um.h"
#define RX_MOD_BASE(x) (x-vr_uh-rx_window_size)%rx_mod
#define RX_MOD_BASE(x) (x-vr_uh-cfg.rx_window_size)%cfg.rx_mod
namespace srslte {
@ -65,41 +65,28 @@ void rlc_um::init(srslte::log *log_,
reordering_timeout_id = mac_timers->get_unique_id();
}
void rlc_um::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg)
void rlc_um::configure(srslte_rlc_config_t cnfg_)
{
switch(cnfg->rlc_mode)
cfg = cnfg_.um;
switch(cnfg_.rlc_mode)
{
case LIBLTE_RRC_RLC_MODE_UM_BI:
t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_bi_rlc.t_reordering];
rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_bi_rlc.sn_field_len;
rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == rx_sn_field_length) ? 16 : 512;
rx_mod = (RLC_UMD_SN_SIZE_5_BITS == rx_sn_field_length) ? 32 : 1024;
tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_bi_rlc.sn_field_len;
tx_mod = (RLC_UMD_SN_SIZE_5_BITS == tx_sn_field_length) ? 32 : 1024;
log->info("%s configured in %s mode: "
"t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n",
rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode],
t_reordering,
rlc_umd_sn_size_num[rx_sn_field_length],
rlc_umd_sn_size_num[tx_sn_field_length]);
rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode],
cfg.t_reordering, cfg.rx_sn_field_length, cfg.tx_sn_field_length);
break;
case LIBLTE_RRC_RLC_MODE_UM_UNI_UL:
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;
log->info("%s configured in %s mode: tx_sn_field_length=%u bits\n",
rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode],
rlc_umd_sn_size_num[tx_sn_field_length]);
rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode],
cfg.tx_sn_field_length);
break;
case LIBLTE_RRC_RLC_MODE_UM_UNI_DL:
t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_uni_rlc.t_reordering];
rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_uni_rlc.sn_field_len;
rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == rx_sn_field_length) ? 16 : 512;
rx_mod = (RLC_UMD_SN_SIZE_5_BITS == rx_sn_field_length) ? 32 : 1024;
log->info("%s configured in %s mode: "
"t_reordering=%d ms, rx_sn_field_length=%u bits\n",
rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode],
liblte_rrc_t_reordering_num[t_reordering],
rlc_umd_sn_size_num[rx_sn_field_length]);
rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode],
cfg.t_reordering, cfg.rx_sn_field_length);
break;
default:
log->error("RLC configuration mode not recognized\n");
@ -229,7 +216,7 @@ void rlc_um::timer_expired(uint32_t timeout_id)
rx_sdu->reset();
while(RX_MOD_BASE(vr_ur) < RX_MOD_BASE(vr_ux))
{
vr_ur = (vr_ur + 1)%rx_mod;
vr_ur = (vr_ur + 1)%cfg.rx_mod;
log->debug("Entering Reassemble from timeout id=%d\n", timeout_id);
reassemble_rx_sdus();
log->debug("Finished reassemble from timeout id=%d\n", timeout_id);
@ -237,7 +224,7 @@ void rlc_um::timer_expired(uint32_t timeout_id)
mac_timers->get(reordering_timeout_id)->stop();
if(RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur))
{
mac_timers->get(reordering_timeout_id)->set(this, t_reordering);
mac_timers->get(reordering_timeout_id)->set(this, cfg.t_reordering);
mac_timers->get(reordering_timeout_id)->run();
vr_ux = vr_uh;
}
@ -274,7 +261,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
header.fi = RLC_FI_FIELD_START_AND_END_ALIGNED;
header.sn = vt_us;
header.N_li = 0;
header.sn_size = tx_sn_field_length;
header.sn_size = cfg.tx_sn_field_length;
uint32_t to_move = 0;
uint32_t last_li = 0;
@ -347,7 +334,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
// Set SN
header.sn = vt_us;
vt_us = (vt_us + 1)%tx_mod;
vt_us = (vt_us + 1)%cfg.tx_mod;
// Add header and TX
log->debug("%s packing PDU with length %d\n", rrc->get_rb_name(lcid).c_str(), pdu->N_bytes);
@ -365,12 +352,12 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
{
std::map<uint32_t, rlc_umd_pdu_t>::iterator it;
rlc_umd_pdu_header_t header;
rlc_um_read_data_pdu_header(payload, nof_bytes, rx_sn_field_length, &header);
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",
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-cfg.rx_window_size) &&
RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ur))
{
log->info("%s SN: %d outside rx window [%d:%d] - discarding\n",
@ -403,7 +390,7 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
// Update vr_uh
if(!inside_reordering_window(header.sn))
vr_uh = (header.sn + 1)%rx_mod;
vr_uh = (header.sn + 1)%cfg.rx_mod;
// Reassemble and deliver SDUs, while updating vr_ur
log->debug("Entering Reassemble from received PDU\n");
@ -423,7 +410,7 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
{
if(RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur))
{
mac_timers->get(reordering_timeout_id)->set(this, t_reordering);
mac_timers->get(reordering_timeout_id)->set(this, cfg.t_reordering);
mac_timers->get(reordering_timeout_id)->run();
vr_ux = vr_uh;
}
@ -452,7 +439,7 @@ void rlc_um::reassemble_rx_sdus()
rx_sdu->N_bytes += len;
rx_window[vr_ur].buf->msg += len;
rx_window[vr_ur].buf->N_bytes -= len;
if((pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) || (vr_ur != ((vr_ur_in_rx_sdu+1)%rx_mod))) {
if((pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) || (vr_ur != ((vr_ur_in_rx_sdu+1)%cfg.rx_mod))) {
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();
} else {
@ -489,7 +476,7 @@ void rlc_um::reassemble_rx_sdus()
rx_window.erase(vr_ur);
}
vr_ur = (vr_ur + 1)%rx_mod;
vr_ur = (vr_ur + 1)%cfg.rx_mod;
}
@ -502,11 +489,11 @@ void rlc_um::reassemble_rx_sdus()
int len = rx_window[vr_ur].header.li[i];
memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, len);
log->debug("Concatenating %d bytes in to current length %d. rx_window remaining bytes=%d, vr_ur_in_rx_sdu=%d, vr_ur=%d, rx_mod=%d, last_mod=%d\n",
len, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes, vr_ur_in_rx_sdu, vr_ur, rx_mod, (vr_ur_in_rx_sdu+1)%rx_mod);
len, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes, vr_ur_in_rx_sdu, vr_ur, cfg.rx_mod, (vr_ur_in_rx_sdu+1)%cfg.rx_mod);
rx_sdu->N_bytes += len;
rx_window[vr_ur].buf->msg += len;
rx_window[vr_ur].buf->N_bytes -= len;
if((pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) || (vr_ur != ((vr_ur_in_rx_sdu+1)%rx_mod))) {
if((pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) || (vr_ur != ((vr_ur_in_rx_sdu+1)%cfg.rx_mod))) {
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();
} else {
@ -542,13 +529,13 @@ void rlc_um::reassemble_rx_sdus()
pool->deallocate(rx_window[vr_ur].buf);
rx_window.erase(vr_ur);
vr_ur = (vr_ur + 1)%rx_mod;
vr_ur = (vr_ur + 1)%cfg.rx_mod;
}
}
bool rlc_um::inside_reordering_window(uint16_t sn)
{
if(RX_MOD_BASE(sn) >= RX_MOD_BASE(vr_uh-rx_window_size) &&
if(RX_MOD_BASE(sn) >= RX_MOD_BASE(vr_uh-cfg.rx_window_size) &&
RX_MOD_BASE(sn) < RX_MOD_BASE(vr_uh))
{
return true;

@ -102,6 +102,7 @@ void basic_test()
cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4;
cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25;
cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4;
cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5;
rlc1.configure(&cnfg);
rlc2.configure(&cnfg);
@ -181,6 +182,7 @@ void concat_test()
cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4;
cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25;
cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4;
cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5;
rlc1.configure(&cnfg);
rlc2.configure(&cnfg);
@ -245,6 +247,7 @@ void segment_test()
cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4;
cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25;
cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4;
cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5;
rlc1.configure(&cnfg);
rlc2.configure(&cnfg);
@ -327,6 +330,7 @@ void retx_test()
cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4;
cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25;
cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4;
cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5;
rlc1.configure(&cnfg);
rlc2.configure(&cnfg);
@ -423,6 +427,7 @@ void resegment_test_1()
cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4;
cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25;
cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4;
cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5;
rlc1.configure(&cnfg);
rlc2.configure(&cnfg);
@ -532,6 +537,7 @@ void resegment_test_2()
cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4;
cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25;
cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4;
cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5;
rlc1.configure(&cnfg);
rlc2.configure(&cnfg);
@ -638,6 +644,7 @@ void resegment_test_3()
cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4;
cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25;
cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4;
cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5;
rlc1.configure(&cnfg);
rlc2.configure(&cnfg);
@ -740,6 +747,7 @@ void resegment_test_4()
cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4;
cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25;
cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4;
cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5;
rlc1.configure(&cnfg);
rlc2.configure(&cnfg);
@ -842,6 +850,7 @@ void resegment_test_5()
cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4;
cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25;
cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4;
cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5;
rlc1.configure(&cnfg);
rlc2.configure(&cnfg);
@ -943,6 +952,7 @@ void resegment_test_6()
cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4;
cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25;
cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4;
cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5;
rlc1.configure(&cnfg);
rlc2.configure(&cnfg);

@ -50,7 +50,7 @@ public:
void add_user(uint16_t rnti);
void rem_user(uint16_t rnti);
void add_bearer(uint16_t rnti, uint32_t lcid);
void add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg);
void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_rlc_config_t cnfg);
// rlc_interface_pdcp
void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu);

@ -98,7 +98,7 @@ void rlc::add_bearer(uint16_t rnti, uint32_t lcid)
}
}
void rlc::add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT* cnfg)
void rlc::add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_rlc_config_t cnfg)
{
if (users.count(rnti)) {
users[rnti].rlc->add_bearer(lcid, cnfg);

@ -1341,7 +1341,7 @@ void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg)
{
rlc->add_bearer(srb_cnfg->srb_id);
}else{
rlc->add_bearer(srb_cnfg->srb_id, &srb_cnfg->rlc_explicit_cnfg);
rlc->add_bearer(srb_cnfg->srb_id, srslte_rlc_config_t(&srb_cnfg->rlc_explicit_cnfg));
}
}
@ -1409,7 +1409,7 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg)
// TODO: setup PDCP security (using k_up_enc)
// Setup RLC
rlc->add_bearer(lcid, &drb_cnfg->rlc_cnfg);
rlc->add_bearer(lcid, srslte_rlc_config_t(&drb_cnfg->rlc_cnfg));
// Setup MAC
uint8_t log_chan_group = 0;

Loading…
Cancel
Save