mirror of https://github.com/PentHertz/srsLTE.git
refactor RLC to use RAT-agnostic config
This commit is contained in:
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…
Reference in New Issue