mirror of https://github.com/PentHertz/srsLTE.git
Add RLC suspend and resume
This commit is contained in:
parent
db196cc052
commit
8c41625599
|
@ -275,15 +275,16 @@ public:
|
|||
class rlc_interface_rrc
|
||||
{
|
||||
public:
|
||||
virtual void reset() = 0;
|
||||
virtual void reestablish() = 0;
|
||||
virtual void reestablish(uint32_t lcid) = 0;
|
||||
virtual void reset() = 0;
|
||||
virtual void reestablish() = 0;
|
||||
virtual void reestablish(uint32_t lcid) = 0;
|
||||
virtual void add_bearer(uint32_t lcid, srslte::rlc_config_t cnfg) = 0;
|
||||
virtual void add_bearer_mrb(uint32_t lcid) = 0;
|
||||
virtual void del_bearer(uint32_t lcid) = 0;
|
||||
virtual void add_bearer_mrb(uint32_t lcid) = 0;
|
||||
virtual void del_bearer(uint32_t lcid) = 0;
|
||||
virtual void suspend_bearer(uint32_t lcid) = 0;
|
||||
virtual void resume_bearer(uint32_t lcid) = 0;
|
||||
virtual void change_lcid(uint32_t old_lcid, uint32_t new_lcid) = 0;
|
||||
virtual bool has_bearer(uint32_t lcid) = 0;
|
||||
virtual void change_lcid(uint32_t old_lcid, uint32_t new_lcid) = 0;
|
||||
virtual bool has_bearer(uint32_t lcid) = 0;
|
||||
virtual bool has_data(const uint32_t lcid) = 0;
|
||||
virtual void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking = true) = 0;
|
||||
};
|
||||
|
|
|
@ -80,6 +80,7 @@ public:
|
|||
void add_bearer_mrb(uint32_t lcid);
|
||||
void del_bearer(uint32_t lcid);
|
||||
void del_bearer_mrb(uint32_t lcid);
|
||||
void suspend_bearer(uint32_t lcid);
|
||||
void resume_bearer(uint32_t lcid);
|
||||
void change_lcid(uint32_t old_lcid, uint32_t new_lcid);
|
||||
bool has_bearer(uint32_t lcid);
|
||||
|
|
|
@ -70,7 +70,6 @@ public:
|
|||
srsue::rrc_interface_rlc* rrc_,
|
||||
srslte::mac_interface_timers* mac_timers_);
|
||||
~rlc_am();
|
||||
bool resume();
|
||||
bool configure(rlc_config_t cfg_);
|
||||
void reestablish();
|
||||
void stop();
|
||||
|
@ -283,7 +282,6 @@ private:
|
|||
mac_interface_timers* mac_timers = nullptr;
|
||||
uint32_t lcid = 0;
|
||||
rlc_config_t cfg = {};
|
||||
bool has_configuration = false;
|
||||
std::string rb_name;
|
||||
|
||||
static const int poll_periodicity = 8; // After how many data PDUs a status PDU shall be requested
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#ifndef SRSLTE_RLC_COMMON_H
|
||||
#define SRSLTE_RLC_COMMON_H
|
||||
|
||||
#include "srslte/common/block_queue.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -141,11 +143,43 @@ public:
|
|||
const static int RLC_BUFFER_NOF_PDU = 128;
|
||||
|
||||
virtual ~rlc_common() {}
|
||||
virtual bool configure(rlc_config_t cnfg) = 0;
|
||||
virtual bool resume() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void reestablish() = 0;
|
||||
virtual void empty_queue() = 0;
|
||||
virtual bool configure(rlc_config_t cnfg) = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void reestablish() = 0;
|
||||
virtual void empty_queue() = 0;
|
||||
|
||||
bool suspend()
|
||||
{
|
||||
if (is_suspended) {
|
||||
return false;
|
||||
}
|
||||
is_suspended = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pops all PDUs from queue and calls write_pdu() method for the bearer type
|
||||
bool resume()
|
||||
{
|
||||
if (!is_suspended) {
|
||||
return false;
|
||||
}
|
||||
pdu_t p;
|
||||
// Do not block
|
||||
while (rx_pdu_resume_queue.try_pop(&p)) {
|
||||
write_pdu(p.payload, p.nof_bytes);
|
||||
}
|
||||
is_suspended = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void write_pdu_s(uint8_t* payload, uint32_t nof_bytes)
|
||||
{
|
||||
if (is_suspended) {
|
||||
queue_pdu(payload, nof_bytes);
|
||||
} else {
|
||||
write_pdu(payload, nof_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
virtual rlc_mode_t get_mode() = 0;
|
||||
virtual uint32_t get_bearer() = 0;
|
||||
|
@ -162,6 +196,27 @@ public:
|
|||
virtual uint32_t get_buffer_state() = 0;
|
||||
virtual int read_pdu(uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||
virtual void write_pdu(uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||
|
||||
private:
|
||||
bool is_suspended = false;
|
||||
|
||||
// Enqueues the PDU in the resume queue
|
||||
void queue_pdu(uint8_t* payload, uint32_t nof_bytes)
|
||||
{
|
||||
pdu_t p = {payload, nof_bytes};
|
||||
// Do not block ever
|
||||
if (!rx_pdu_resume_queue.try_push(p)) {
|
||||
fprintf(stderr, "Error dropping PDUs while bearer suspended. Queue should be unbounded\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t* payload;
|
||||
uint32_t nof_bytes;
|
||||
} pdu_t;
|
||||
|
||||
block_queue<pdu_t> rx_pdu_resume_queue;
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
|
|
@ -42,7 +42,6 @@ public:
|
|||
uint32_t queue_len = 16);
|
||||
~rlc_tm();
|
||||
bool configure(rlc_config_t cnfg);
|
||||
bool resume();
|
||||
void stop();
|
||||
void reestablish();
|
||||
void empty_queue();
|
||||
|
|
|
@ -50,7 +50,6 @@ public:
|
|||
mac_interface_timers* mac_timers_);
|
||||
~rlc_um();
|
||||
bool configure(rlc_config_t cnfg);
|
||||
bool resume();
|
||||
void reestablish();
|
||||
void stop();
|
||||
void empty_queue();
|
||||
|
@ -204,7 +203,6 @@ private:
|
|||
srslte::log* log = nullptr;
|
||||
uint32_t lcid = 0;
|
||||
rlc_config_t cfg = {};
|
||||
bool has_configuration = false;
|
||||
std::string rb_name;
|
||||
byte_buffer_pool* pool = nullptr;
|
||||
|
||||
|
|
|
@ -143,6 +143,7 @@ void rlc::reestablish(uint32_t lcid)
|
|||
{
|
||||
pthread_rwlock_rdlock(&rwlock);
|
||||
if (valid_lcid(lcid)) {
|
||||
rlc_log->info("Reestablishing LCID %d\n", lcid);
|
||||
rlc_array.at(lcid)->reestablish();
|
||||
} else {
|
||||
rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid);
|
||||
|
@ -309,7 +310,7 @@ void rlc::write_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes)
|
|||
{
|
||||
pthread_rwlock_rdlock(&rwlock);
|
||||
if (valid_lcid(lcid)) {
|
||||
rlc_array.at(lcid)->write_pdu(payload, nof_bytes);
|
||||
rlc_array.at(lcid)->write_pdu_s(payload, nof_bytes);
|
||||
} else {
|
||||
rlc_log->warning("LCID %d doesn't exist. Dropping PDU.\n", lcid);
|
||||
}
|
||||
|
@ -381,8 +382,7 @@ void rlc::add_bearer(uint32_t lcid, rlc_config_t cnfg)
|
|||
rlc_common *rlc_entity = NULL;
|
||||
|
||||
if (not valid_lcid(lcid)) {
|
||||
switch(cnfg.rlc_mode)
|
||||
{
|
||||
switch (cnfg.rlc_mode) {
|
||||
case rlc_mode_t::tm:
|
||||
rlc_entity = new rlc_tm(rlc_log, lcid, pdcp, rrc, mac_timers);
|
||||
break;
|
||||
|
@ -397,24 +397,24 @@ void rlc::add_bearer(uint32_t lcid, rlc_config_t cnfg)
|
|||
goto unlock_and_exit;
|
||||
}
|
||||
|
||||
// configure and add to array
|
||||
if (cnfg.rlc_mode != rlc_mode_t::tm) {
|
||||
if (not rlc_entity->configure(cnfg)) {
|
||||
rlc_log->error("Error configuring RLC entity\n.");
|
||||
goto delete_and_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (not rlc_array.insert(rlc_map_pair_t(lcid, rlc_entity)).second) {
|
||||
rlc_log->error("Error inserting RLC entity in to array\n.");
|
||||
goto delete_and_exit;
|
||||
}
|
||||
rlc_log->info("Added radio bearer %s in %s\n", rrc->get_rb_name(lcid).c_str(), to_string(cnfg.rlc_mode).c_str());
|
||||
goto unlock_and_exit;
|
||||
} else {
|
||||
rlc_log->warning("Bearer %s already created.\n", rrc->get_rb_name(lcid).c_str());
|
||||
rlc_entity = NULL;
|
||||
}
|
||||
|
||||
// configure and add to array
|
||||
if (cnfg.rlc_mode != rlc_mode_t::tm) {
|
||||
if (not rlc_array.at(lcid)->configure(cnfg)) {
|
||||
rlc_log->error("Error configuring RLC entity\n.");
|
||||
goto delete_and_exit;
|
||||
}
|
||||
}
|
||||
|
||||
rlc_log->info("Configured radio bearer %s in %s\n", rrc->get_rb_name(lcid).c_str(), to_string(cnfg.rlc_mode).c_str());
|
||||
|
||||
delete_and_exit:
|
||||
if (rlc_entity) {
|
||||
delete(rlc_entity);
|
||||
|
@ -521,15 +521,33 @@ exit:
|
|||
pthread_rwlock_unlock(&rwlock);
|
||||
}
|
||||
|
||||
void rlc::resume_bearer(uint32_t lcid)
|
||||
void rlc::suspend_bearer(uint32_t lcid)
|
||||
{
|
||||
pthread_rwlock_wrlock(&rwlock);
|
||||
|
||||
if (valid_lcid(lcid)) {
|
||||
if (rlc_array.at(lcid)->suspend()) {
|
||||
rlc_log->info("Suspended radio bearer %s\n", rrc->get_rb_name(lcid).c_str());
|
||||
} else {
|
||||
rlc_log->error("Error suspending RLC entity: bearer already suspended\n.");
|
||||
}
|
||||
} else {
|
||||
rlc_log->error("Suspending bearer: bearer %s not configured.\n", rrc->get_rb_name(lcid).c_str());
|
||||
}
|
||||
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
}
|
||||
|
||||
void rlc::resume_bearer(uint32_t lcid)
|
||||
{
|
||||
pthread_rwlock_wrlock(&rwlock);
|
||||
|
||||
rlc_log->info("Resuming radio bearer %s\n", rrc->get_rb_name(lcid).c_str());
|
||||
if (valid_lcid(lcid)) {
|
||||
if (rlc_array.at(lcid)->resume()) {
|
||||
rlc_log->info("Resumed radio bearer %s\n", rrc->get_rb_name(lcid).c_str());
|
||||
} else {
|
||||
rlc_log->error("Error resuming RLC entity\n.");
|
||||
rlc_log->error("Error resuming RLC entity: bearer not suspended\n.");
|
||||
}
|
||||
} else {
|
||||
rlc_log->error("Resuming bearer: bearer %s not configured.\n", rrc->get_rb_name(lcid).c_str());
|
||||
|
|
|
@ -51,12 +51,14 @@ rlc_am::~rlc_am()
|
|||
{
|
||||
}
|
||||
|
||||
bool rlc_am::resume()
|
||||
// Applies new configuration. Must be just reestablished or initiated
|
||||
bool rlc_am::configure(rlc_config_t cfg_)
|
||||
{
|
||||
if (not has_configuration) {
|
||||
log->error("Error resuming bearer: no previous configuration found\n");
|
||||
return false;
|
||||
}
|
||||
// determine bearer name and configure Rx/Tx objects
|
||||
rb_name = rrc->get_rb_name(lcid);
|
||||
|
||||
// store config
|
||||
cfg = cfg_;
|
||||
|
||||
if (not rx.configure(cfg.am)) {
|
||||
log->error("Error resuming bearer (RX)\n");
|
||||
|
@ -68,34 +70,18 @@ bool rlc_am::resume()
|
|||
return false;
|
||||
}
|
||||
|
||||
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",
|
||||
rb_name.c_str(),
|
||||
cfg.am.t_poll_retx,
|
||||
cfg.am.poll_pdu,
|
||||
cfg.am.poll_byte,
|
||||
cfg.am.max_retx_thresh,
|
||||
cfg.am.t_reordering,
|
||||
cfg.am.t_status_prohibit);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rlc_am::configure(rlc_config_t cfg_)
|
||||
{
|
||||
// determine bearer name and configure Rx/Tx objects
|
||||
rb_name = rrc->get_rb_name(lcid);
|
||||
|
||||
// store config
|
||||
cfg = cfg_;
|
||||
has_configuration = true;
|
||||
|
||||
if (resume()) {
|
||||
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",
|
||||
rb_name.c_str(),
|
||||
cfg.am.t_poll_retx,
|
||||
cfg.am.poll_pdu,
|
||||
cfg.am.poll_byte,
|
||||
cfg.am.max_retx_thresh,
|
||||
cfg.am.t_reordering,
|
||||
cfg.am.t_status_prohibit);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void rlc_am::empty_queue()
|
||||
{
|
||||
// Drop all messages in TX SDU queue
|
||||
|
|
|
@ -49,11 +49,6 @@ bool rlc_tm::configure(rlc_config_t cnfg)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool rlc_tm::resume()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void rlc_tm::empty_queue()
|
||||
{
|
||||
// Drop all messages in TX queue
|
||||
|
|
|
@ -48,12 +48,13 @@ rlc_um::~rlc_um()
|
|||
stop();
|
||||
}
|
||||
|
||||
bool rlc_um::resume()
|
||||
bool rlc_um::configure(rlc_config_t cnfg_)
|
||||
{
|
||||
if (not has_configuration) {
|
||||
log->error("Error resuming bearer: no previous configuration found\n");
|
||||
return false;
|
||||
}
|
||||
// determine bearer name and configure Rx/Tx objects
|
||||
rb_name = get_rb_name(rrc, lcid, cnfg_.um.is_mrb);
|
||||
|
||||
// store config
|
||||
cfg = cnfg_;
|
||||
|
||||
if (not rx.configure(cfg, rb_name)) {
|
||||
return false;
|
||||
|
@ -63,31 +64,15 @@ bool rlc_um::resume()
|
|||
return false;
|
||||
}
|
||||
|
||||
log->info("%s configured in %s: t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n",
|
||||
rb_name.c_str(),
|
||||
srslte::to_string(cnfg_.rlc_mode).c_str(),
|
||||
cfg.um.t_reordering,
|
||||
srslte::to_number(cfg.um.rx_sn_field_length),
|
||||
srslte::to_number(cfg.um.tx_sn_field_length));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rlc_um::configure(rlc_config_t cnfg_)
|
||||
{
|
||||
// determine bearer name and configure Rx/Tx objects
|
||||
rb_name = get_rb_name(rrc, lcid, cnfg_.um.is_mrb);
|
||||
|
||||
// store config
|
||||
cfg = cnfg_;
|
||||
has_configuration = true;
|
||||
|
||||
if (resume()) {
|
||||
log->info("%s configured in %s: t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n",
|
||||
rb_name.c_str(),
|
||||
srslte::to_string(cnfg_.rlc_mode).c_str(),
|
||||
cfg.um.t_reordering,
|
||||
srslte::to_number(cfg.um.rx_sn_field_length),
|
||||
srslte::to_number(cfg.um.tx_sn_field_length));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool rlc_um::rlc_um_rx::configure(rlc_config_t cnfg_, std::string rb_name_)
|
||||
{
|
||||
cfg = cnfg_.um;
|
||||
|
|
|
@ -47,6 +47,10 @@ add_executable(rlc_um_test rlc_um_test.cc)
|
|||
target_link_libraries(rlc_um_test srslte_upper srslte_phy)
|
||||
add_test(rlc_um_test rlc_um_test)
|
||||
|
||||
add_executable(rlc_common_test rlc_common_test.cc)
|
||||
target_link_libraries(rlc_common_test srslte_upper srslte_phy)
|
||||
add_test(rlc_common_test rlc_common_test)
|
||||
|
||||
########################################################################
|
||||
# Option to run command after build (useful for remote builds)
|
||||
########################################################################
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Copyright 2013-2019 Software Radio Systems Limited
|
||||
*
|
||||
* This file is part of srsLTE.
|
||||
*
|
||||
* srsLTE 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.
|
||||
*
|
||||
* srsLTE 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srslte/common/log_filter.h"
|
||||
#include "srslte/upper/rlc.h"
|
||||
#include <iostream>
|
||||
|
||||
#define TESTASSERT(cond) \
|
||||
{ \
|
||||
if (!(cond)) { \
|
||||
std::cout << "[" << __FUNCTION__ << "][Line " << __LINE__ << "]: FAIL at " << (#cond) << std::endl; \
|
||||
return -1; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define MAX_NBUFS 100
|
||||
#define NBUFS 5
|
||||
|
||||
using namespace srslte;
|
||||
using namespace srsue;
|
||||
using namespace asn1::rrc;
|
||||
|
||||
class mac_dummy_timers : public srslte::mac_interface_timers
|
||||
{
|
||||
public:
|
||||
srslte::timers::timer* timer_get(uint32_t timer_id) { return &t; }
|
||||
uint32_t timer_get_unique_id() { return 0; }
|
||||
void step() { t.step(); }
|
||||
void timer_release_id(uint32_t timer_id) {}
|
||||
|
||||
private:
|
||||
srslte::timers::timer t;
|
||||
};
|
||||
|
||||
class rlc_tester : public pdcp_interface_rlc, public rrc_interface_rlc
|
||||
{
|
||||
public:
|
||||
rlc_tester()
|
||||
{
|
||||
bzero(sdus, sizeof(sdus));
|
||||
n_sdus = 0;
|
||||
expected_sdu_len = 0;
|
||||
}
|
||||
|
||||
// PDCP interface
|
||||
void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu)
|
||||
{
|
||||
if (lcid != 3 && sdu->N_bytes != expected_sdu_len) {
|
||||
printf("Received PDU with size %d, expected %d. Exiting.\n", sdu->N_bytes, expected_sdu_len);
|
||||
exit(-1);
|
||||
}
|
||||
sdus[n_sdus++] = std::move(sdu);
|
||||
}
|
||||
void write_pdu_bcch_bch(unique_byte_buffer_t sdu) {}
|
||||
void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {}
|
||||
void write_pdu_pcch(unique_byte_buffer_t sdu) {}
|
||||
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) { sdus[n_sdus++] = std::move(sdu); }
|
||||
|
||||
// RRC interface
|
||||
void max_retx_attempted() {}
|
||||
std::string get_rb_name(uint32_t lcid) { return std::string("TestRB"); }
|
||||
void set_expected_sdu_len(uint32_t len) { expected_sdu_len = len; }
|
||||
|
||||
unique_byte_buffer_t sdus[MAX_NBUFS];
|
||||
int n_sdus;
|
||||
uint32_t expected_sdu_len;
|
||||
};
|
||||
|
||||
int basic_test()
|
||||
{
|
||||
srslte::log_filter log1("RLC_1");
|
||||
srslte::log_filter log2("RLC_2");
|
||||
log1.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||
log1.set_hex_limit(-1);
|
||||
log2.set_hex_limit(-1);
|
||||
rlc_tester tester;
|
||||
mac_dummy_timers timers;
|
||||
|
||||
int len = 0;
|
||||
|
||||
rlc rlc1(&log1);
|
||||
rlc rlc2(&log2);
|
||||
|
||||
rlc1.init(&tester, &tester, &timers, 0);
|
||||
rlc2.init(&tester, &tester, &timers, 0);
|
||||
|
||||
rlc_config_t cnfg = rlc_config_t::default_rlc_um_config(10);
|
||||
cnfg.rlc_mode = rlc_mode_t::um;
|
||||
cnfg.um.t_reordering = 5;
|
||||
cnfg.um.rx_sn_field_length = rlc_umd_sn_size_t::size10bits;
|
||||
cnfg.um.rx_window_size = 512;
|
||||
cnfg.um.rx_mod = 1024;
|
||||
cnfg.um.tx_sn_field_length = rlc_umd_sn_size_t::size10bits;
|
||||
cnfg.um.tx_mod = 1024;
|
||||
|
||||
uint32_t lcid = 1;
|
||||
rlc1.add_bearer(lcid, cnfg);
|
||||
rlc2.add_bearer(lcid, cnfg);
|
||||
|
||||
byte_buffer_pool* pool = byte_buffer_pool::get_instance();
|
||||
unique_byte_buffer_t sdu_bufs[NBUFS];
|
||||
|
||||
tester.set_expected_sdu_len(1);
|
||||
|
||||
// Push 5 SDUs into RLC1
|
||||
for (int i = 0; i < NBUFS; i++) {
|
||||
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
|
||||
*sdu_bufs[i]->msg = i; // Write the index into the buffer
|
||||
sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte
|
||||
rlc1.write_sdu(lcid, std::move(sdu_bufs[i]));
|
||||
}
|
||||
|
||||
TESTASSERT(14 == rlc1.get_buffer_state(lcid));
|
||||
|
||||
// Reestablish
|
||||
rlc1.reestablish(1);
|
||||
|
||||
TESTASSERT(0 == rlc1.get_buffer_state(lcid));
|
||||
|
||||
// Push again 5 SDUs, SN should start from 0
|
||||
for (int i = 0; i < NBUFS; i++) {
|
||||
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
|
||||
*sdu_bufs[i]->msg = i; // Write the index into the buffer
|
||||
sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte
|
||||
rlc1.write_sdu(lcid, std::move(sdu_bufs[i]));
|
||||
}
|
||||
|
||||
TESTASSERT(14 == rlc1.get_buffer_state(lcid));
|
||||
|
||||
// Read 5 PDUs from RLC1 (1 byte each)
|
||||
byte_buffer_t pdu_bufs[NBUFS];
|
||||
for (int i = 0; i < NBUFS; i++) {
|
||||
len = rlc1.read_pdu(lcid, pdu_bufs[i].msg, 4); // 3 bytes for header + payload
|
||||
pdu_bufs[i].N_bytes = len;
|
||||
}
|
||||
|
||||
TESTASSERT(0 == rlc1.get_buffer_state(lcid));
|
||||
|
||||
// Write 5 PDUs into RLC2
|
||||
for (int i = 0; i < NBUFS; i++) {
|
||||
rlc2.write_pdu(lcid, pdu_bufs[i].msg, pdu_bufs[i].N_bytes);
|
||||
}
|
||||
|
||||
// Check they have been passed to PDCP
|
||||
TESTASSERT(NBUFS == tester.n_sdus);
|
||||
|
||||
rlc2.reestablish(lcid);
|
||||
|
||||
tester.n_sdus = 0;
|
||||
|
||||
// Push again
|
||||
for (int i = 0; i < NBUFS; i++) {
|
||||
rlc2.write_pdu(lcid, pdu_bufs[i].msg, pdu_bufs[i].N_bytes);
|
||||
}
|
||||
|
||||
// Check the are again in the buffer
|
||||
TESTASSERT(NBUFS == tester.n_sdus);
|
||||
|
||||
for (int i = 0; i < NBUFS; i++) {
|
||||
TESTASSERT(tester.sdus[i]->N_bytes == 1);
|
||||
TESTASSERT(*(tester.sdus[i]->msg) == i);
|
||||
}
|
||||
|
||||
// Resume unexisting and unsuspended bearer
|
||||
rlc2.resume_bearer(lcid + 1);
|
||||
rlc2.resume_bearer(lcid);
|
||||
|
||||
// Suspend unexisting bearer and twice
|
||||
rlc2.suspend_bearer(lcid + 1);
|
||||
rlc2.suspend_bearer(lcid);
|
||||
rlc2.suspend_bearer(lcid);
|
||||
|
||||
// Reestablish and push again while in suspended
|
||||
rlc2.reestablish(lcid);
|
||||
|
||||
tester.n_sdus = 0;
|
||||
|
||||
// Push again
|
||||
for (int i = 0; i < NBUFS; i++) {
|
||||
rlc2.write_pdu(lcid, pdu_bufs[i].msg, pdu_bufs[i].N_bytes);
|
||||
}
|
||||
|
||||
// Check they are not being passed to PDCP
|
||||
TESTASSERT(0 == tester.n_sdus);
|
||||
|
||||
rlc2.resume_bearer(lcid);
|
||||
|
||||
// Check now they are being passed
|
||||
TESTASSERT(NBUFS == tester.n_sdus);
|
||||
|
||||
for (int i = 0; i < NBUFS; i++) {
|
||||
TESTASSERT(tester.sdus[i]->N_bytes == 1);
|
||||
TESTASSERT(*(tester.sdus[i]->msg) == i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (basic_test()) {
|
||||
return -1;
|
||||
}
|
||||
byte_buffer_pool::get_instance()->cleanup();
|
||||
}
|
|
@ -1812,8 +1812,12 @@ void rrc::proc_con_restablish_request()
|
|||
mac_timers->timer_get(t311)->reset();
|
||||
mac_timers->timer_get(t311)->run();
|
||||
|
||||
// TODO: suspend all RBs except SRB0;
|
||||
// is this that RLC tx queue stops accepting SDUs?
|
||||
// Suspend all RB except SRB0
|
||||
for (int i = 1; i < SRSLTE_N_RADIO_BEARERS; i++) {
|
||||
if (rlc->has_bearer(i)) {
|
||||
rlc->suspend_bearer(i);
|
||||
}
|
||||
}
|
||||
|
||||
// reset MAC;
|
||||
mac->reset();
|
||||
|
@ -3068,7 +3072,7 @@ void rrc::handle_con_reest(rrc_conn_reest_s* setup)
|
|||
// Apply the Radio Resource configuration
|
||||
apply_rr_config_dedicated(&setup->crit_exts.c1().rrc_conn_reest_r8().rr_cfg_ded);
|
||||
|
||||
// Resume SRB1 (if already configured in rr_config, this function does nothing)
|
||||
// Resume SRB1
|
||||
rlc->resume_bearer(1);
|
||||
|
||||
// Send ConnectionSetupComplete message
|
||||
|
|
Loading…
Reference in New Issue