rlc: refactor RLC entity to use smart pointers for holding bearers

this patch mainly modernizes the bearer creation to use smart pointers.
that allows to simplify the error handling.

ue_stack is changed to match new interface. This commit compiles
but doesn't work.
master
Andre Puschmann 4 years ago
parent 6d5391756c
commit 7113e55d53

@ -24,8 +24,8 @@ public:
virtual void reset() = 0; virtual void reset() = 0;
virtual void reestablish() = 0; virtual void reestablish() = 0;
virtual void reestablish(uint32_t lcid) = 0; virtual void reestablish(uint32_t lcid) = 0;
virtual void add_bearer(uint32_t lcid, const srsran::rlc_config_t& cnfg) = 0; virtual int add_bearer(uint32_t lcid, const srsran::rlc_config_t& cnfg) = 0;
virtual void add_bearer_mrb(uint32_t lcid) = 0; virtual int add_bearer_mrb(uint32_t lcid) = 0;
virtual void del_bearer(uint32_t lcid) = 0; virtual void del_bearer(uint32_t lcid) = 0;
virtual void suspend_bearer(uint32_t lcid) = 0; virtual void suspend_bearer(uint32_t lcid) = 0;
virtual void resume_bearer(uint32_t lcid) = 0; virtual void resume_bearer(uint32_t lcid) = 0;

@ -40,12 +40,6 @@ public:
srsran::timer_handler* timers_, srsran::timer_handler* timers_,
uint32_t lcid_); uint32_t lcid_);
void init(srsue::pdcp_interface_rlc* pdcp_,
srsue::rrc_interface_rlc* rrc_,
srsue::rrc_interface_rlc* rrc_nr_,
srsran::timer_handler* timers_,
uint32_t lcid_);
void init(srsue::pdcp_interface_rlc* pdcp_, void init(srsue::pdcp_interface_rlc* pdcp_,
srsue::rrc_interface_rlc* rrc_, srsue::rrc_interface_rlc* rrc_,
srsran::timer_handler* timers_, srsran::timer_handler* timers_,
@ -82,8 +76,8 @@ public:
void reestablish(uint32_t lcid); void reestablish(uint32_t lcid);
void reset(); void reset();
void empty_queue(); void empty_queue();
void add_bearer(uint32_t lcid, const rlc_config_t& cnfg); int add_bearer(uint32_t lcid, const rlc_config_t& cnfg);
void add_bearer_mrb(uint32_t lcid); int add_bearer_mrb(uint32_t lcid);
void del_bearer(uint32_t lcid); void del_bearer(uint32_t lcid);
void del_bearer_mrb(uint32_t lcid); void del_bearer_mrb(uint32_t lcid);
void suspend_bearer(uint32_t lcid); void suspend_bearer(uint32_t lcid);
@ -98,11 +92,10 @@ private:
byte_buffer_pool* pool = nullptr; byte_buffer_pool* pool = nullptr;
srsue::pdcp_interface_rlc* pdcp = nullptr; srsue::pdcp_interface_rlc* pdcp = nullptr;
srsue::rrc_interface_rlc* rrc = nullptr; srsue::rrc_interface_rlc* rrc = nullptr;
srsue::rrc_interface_rlc* rrc_nr = nullptr;
srsran::timer_handler* timers = nullptr; srsran::timer_handler* timers = nullptr;
typedef std::map<uint16_t, rlc_common*> rlc_map_t; typedef std::map<uint16_t, std::unique_ptr<rlc_common> > rlc_map_t;
typedef std::pair<uint16_t, rlc_common*> rlc_map_pair_t; typedef std::pair<uint16_t, std::unique_ptr<rlc_common> > rlc_map_pair_t;
rlc_map_t rlc_array, rlc_array_mrb; rlc_map_t rlc_array, rlc_array_mrb;
pthread_rwlock_t rwlock; pthread_rwlock_t rwlock;

@ -19,42 +19,20 @@
namespace srsran { namespace srsran {
rlc::rlc(const char* logname) : logger(srslog::fetch_basic_logger(logname)) rlc::rlc(const char* logname) : logger(srslog::fetch_basic_logger(logname)), pool(byte_buffer_pool::get_instance())
{ {
pool = byte_buffer_pool::get_instance();
pthread_rwlock_init(&rwlock, NULL); pthread_rwlock_init(&rwlock, NULL);
} }
rlc::~rlc() rlc::~rlc()
{ {
// destroy all remaining entities // destroy all remaining entities
{ srsran::rwlock_write_guard lock(rwlock);
rwlock_write_guard lock(rwlock);
for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) {
delete (it->second);
}
rlc_array.clear(); rlc_array.clear();
for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) {
delete (it->second);
}
rlc_array_mrb.clear(); rlc_array_mrb.clear();
}
pthread_rwlock_destroy(&rwlock); pthread_rwlock_destroy(&rwlock);
} }
void rlc::init(srsue::pdcp_interface_rlc* pdcp_,
srsue::rrc_interface_rlc* rrc_,
srsue::rrc_interface_rlc* rrc_nr_,
srsran::timer_handler* timers_,
uint32_t lcid_)
{
init(pdcp_, rrc_, timers_, lcid_);
rrc_nr = rrc_nr_;
}
void rlc::init(srsue::pdcp_interface_rlc* pdcp_, void rlc::init(srsue::pdcp_interface_rlc* pdcp_,
srsue::rrc_interface_rlc* rrc_, srsue::rrc_interface_rlc* rrc_,
srsran::timer_handler* timers_, srsran::timer_handler* timers_,
@ -171,11 +149,6 @@ void rlc::reset()
{ {
{ {
rwlock_write_guard lock(rwlock); rwlock_write_guard lock(rwlock);
for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) {
it->second->stop();
delete (it->second);
}
rlc_array.clear(); rlc_array.clear();
// the multicast bearer (MRB) is not removed here because eMBMS services continue to be streamed in idle mode (3GPP // the multicast bearer (MRB) is not removed here because eMBMS services continue to be streamed in idle mode (3GPP
// TS 23.246 version 14.1.0 Release 14 section 8) // TS 23.246 version 14.1.0 Release 14 section 8)
@ -399,119 +372,98 @@ bool rlc::has_data(uint32_t lcid)
} }
// Methods modifying the RLC array need to acquire the write-lock // Methods modifying the RLC array need to acquire the write-lock
void rlc::add_bearer(uint32_t lcid, const rlc_config_t& cnfg) int rlc::add_bearer(uint32_t lcid, const rlc_config_t& cnfg)
{ {
rwlock_write_guard lock(rwlock); rwlock_write_guard lock(rwlock);
rlc_common* rlc_entity = nullptr; if (valid_lcid(lcid)) {
logger.error("LCID %d already exists", lcid);
// Check this for later rrc_nr pointer access return SRSRAN_ERROR;
if (cnfg.rat == srsran::srsran_rat_t::nr && rrc_nr == nullptr) {
logger.error("Cannot add/modify RLC entity - missing rrc_nr parent pointer for rat type nr");
return;
} }
if (cnfg.rlc_mode != rlc_mode_t::tm and rlc_array.find(lcid) != rlc_array.end()) { std::unique_ptr<rlc_common> rlc_entity;
if (rlc_array[lcid]->get_mode() != cnfg.rlc_mode) {
logger.info("Switching RLC entity type. Recreating it.");
rlc_array.erase(lcid);
}
}
if (not valid_lcid(lcid)) {
switch (cnfg.rat) {
case srsran_rat_t::lte:
switch (cnfg.rlc_mode) { switch (cnfg.rlc_mode) {
case rlc_mode_t::tm: case rlc_mode_t::tm:
rlc_entity = new rlc_tm(logger, lcid, pdcp, rrc); rlc_entity = std::unique_ptr<rlc_common>(new rlc_tm(logger, lcid, pdcp, rrc));
break; break;
case rlc_mode_t::am: case rlc_mode_t::am:
rlc_entity = new rlc_am_lte(logger, lcid, pdcp, rrc, timers); switch (cnfg.rat) {
break; case srsran_rat_t::lte:
case rlc_mode_t::um: rlc_entity = std::unique_ptr<rlc_common>(new rlc_am_lte(logger, lcid, pdcp, rrc, timers));
rlc_entity = new rlc_um_lte(logger, lcid, pdcp, rrc, timers);
break; break;
default: default:
logger.error("Cannot add RLC entity - invalid mode"); logger.error("AM not supported for this RAT");
return; return SRSRAN_ERROR;
}
if (rlc_entity != nullptr) {
rlc_entity->set_bsr_callback(bsr_callback);
} }
break; break;
case srsran_rat_t::nr:
switch (cnfg.rlc_mode) {
case rlc_mode_t::tm:
rlc_entity = new rlc_tm(logger, lcid, pdcp, rrc_nr);
break;
case rlc_mode_t::um: case rlc_mode_t::um:
rlc_entity = new rlc_um_nr(logger, lcid, pdcp, rrc_nr, timers); switch (cnfg.rat) {
case srsran_rat_t::lte:
rlc_entity = std::unique_ptr<rlc_common>(new rlc_um_lte(logger, lcid, pdcp, rrc, timers));
break;
case srsran_rat_t::nr:
rlc_entity = std::unique_ptr<rlc_common>(new rlc_um_nr(logger, lcid, pdcp, rrc, timers));
break; break;
default: default:
logger.error("Cannot add RLC entity - invalid mode"); logger.error("UM not supported for this RAT");
return; return SRSRAN_ERROR;
} }
break; break;
default: default:
logger.error("RAT not supported"); logger.error("Cannot add RLC entity - invalid mode");
return; return SRSRAN_ERROR;
}
if (not rlc_array.insert(rlc_map_pair_t(lcid, rlc_entity)).second) {
logger.error("Error inserting RLC entity in to array.");
goto delete_and_exit;
} }
logger.info("Added %s radio bearer with LCID %d in %s", to_string(cnfg.rat), lcid, to_string(cnfg.rlc_mode)); // make sure entity has been created
rlc_entity = NULL; if (rlc_entity == nullptr) {
} else { logger.error("Couldn't allocate new RLC entity");
logger.info("LCID %d already exists", lcid); return SRSRAN_ERROR;
} }
// configure and add to array // configure entity
if (cnfg.rlc_mode != rlc_mode_t::tm and rlc_array.find(lcid) != rlc_array.end()) { if (cnfg.rlc_mode != rlc_mode_t::tm) {
if (not rlc_array.at(lcid)->configure(cnfg)) { if (not rlc_entity->configure(cnfg)) {
logger.error("Error configuring RLC entity."); logger.error("Error configuring RLC entity.");
goto delete_and_exit; return SRSRAN_ERROR;
} }
} }
logger.info("Configured %s radio bearer with LCID %d in %s", to_string(cnfg.rat), lcid, to_string(cnfg.rlc_mode)); rlc_entity->set_bsr_callback(bsr_callback);
delete_and_exit: if (not rlc_array.insert(rlc_map_pair_t(lcid, std::move(rlc_entity))).second) {
if (rlc_entity) { logger.error("Error inserting RLC entity in to array.");
delete (rlc_entity); return SRSRAN_ERROR;
} }
logger.info("Added %s radio bearer with LCID %d in %s", to_string(cnfg.rat), lcid, to_string(cnfg.rlc_mode));
return SRSRAN_SUCCESS;
} }
void rlc::add_bearer_mrb(uint32_t lcid) int rlc::add_bearer_mrb(uint32_t lcid)
{ {
rwlock_write_guard lock(rwlock); rwlock_write_guard lock(rwlock);
rlc_common* rlc_entity = NULL;
if (not valid_lcid_mrb(lcid)) { if (not valid_lcid_mrb(lcid)) {
rlc_entity = new rlc_um_lte(logger, lcid, pdcp, rrc, timers); std::unique_ptr<rlc_common> rlc_entity =
std::unique_ptr<rlc_common>(new rlc_um_lte(logger, lcid, pdcp, rrc, timers));
// configure and add to array // configure and add to array
if (not rlc_entity->configure(rlc_config_t::mch_config())) { if (rlc_entity or rlc_entity->configure(rlc_config_t::mch_config()) == false) {
logger.error("Error configuring RLC entity."); logger.error("Error configuring RLC entity.");
goto delete_and_exit; return SRSRAN_ERROR;
} }
if (rlc_array_mrb.count(lcid) == 0) { if (rlc_array_mrb.count(lcid) == 0) {
if (not rlc_array_mrb.insert(rlc_map_pair_t(lcid, rlc_entity)).second) { if (not rlc_array_mrb.insert(rlc_map_pair_t(lcid, std::move(rlc_entity))).second) {
logger.error("Error inserting RLC entity in to array."); logger.error("Error inserting RLC entity in to array.");
goto delete_and_exit; return SRSRAN_ERROR;
} }
} }
logger.warning("Added bearer MRB%d with mode RLC_UM", lcid); logger.info("Added bearer MRB%d with mode RLC_UM", lcid);
return;
} else { } else {
logger.warning("Bearer MRB%d already created.", lcid); logger.warning("Bearer MRB%d already created.", lcid);
} }
delete_and_exit: return SRSRAN_SUCCESS;
if (rlc_entity != NULL) {
delete (rlc_entity);
}
} }
void rlc::del_bearer(uint32_t lcid) void rlc::del_bearer(uint32_t lcid)
@ -521,7 +473,6 @@ void rlc::del_bearer(uint32_t lcid)
if (valid_lcid(lcid)) { if (valid_lcid(lcid)) {
rlc_map_t::iterator it = rlc_array.find(lcid); rlc_map_t::iterator it = rlc_array.find(lcid);
it->second->stop(); it->second->stop();
delete (it->second);
rlc_array.erase(it); rlc_array.erase(it);
logger.info("Deleted RLC bearer with LCID %d", lcid); logger.info("Deleted RLC bearer with LCID %d", lcid);
} else { } else {
@ -536,9 +487,8 @@ void rlc::del_bearer_mrb(uint32_t lcid)
if (valid_lcid_mrb(lcid)) { if (valid_lcid_mrb(lcid)) {
rlc_map_t::iterator it = rlc_array_mrb.find(lcid); rlc_map_t::iterator it = rlc_array_mrb.find(lcid);
it->second->stop(); it->second->stop();
delete (it->second);
rlc_array_mrb.erase(it); rlc_array_mrb.erase(it);
logger.warning("Deleted RLC MRB bearer with LCID %d", lcid); logger.info("Deleted RLC MRB bearer with LCID %d", lcid);
} else { } else {
logger.error("Can't delete bearer with LCID %d. Bearer doesn't exist.", lcid); logger.error("Can't delete bearer with LCID %d. Bearer doesn't exist.", lcid);
} }
@ -552,8 +502,8 @@ void rlc::change_lcid(uint32_t old_lcid, uint32_t new_lcid)
if (valid_lcid(old_lcid) && not valid_lcid(new_lcid)) { if (valid_lcid(old_lcid) && not valid_lcid(new_lcid)) {
// insert old rlc entity into new LCID // insert old rlc entity into new LCID
rlc_map_t::iterator it = rlc_array.find(old_lcid); rlc_map_t::iterator it = rlc_array.find(old_lcid);
rlc_common* rlc_entity = it->second; std::unique_ptr<rlc_common> rlc_entity = std::move(it->second);
if (not rlc_array.insert(rlc_map_pair_t(new_lcid, rlc_entity)).second) { if (not rlc_array.insert(rlc_map_pair_t(new_lcid, std::move(rlc_entity))).second) {
logger.error("Error inserting RLC entity into array."); logger.error("Error inserting RLC entity into array.");
return; return;
} }

@ -48,8 +48,8 @@ class dummy_rlc : public rlc_interface_rrc
void reset() {} void reset() {}
void reestablish() {} void reestablish() {}
void reestablish(uint32_t lcid) {} void reestablish(uint32_t lcid) {}
void add_bearer(uint32_t lcid, const srsran::rlc_config_t& cnfg) {} int add_bearer(uint32_t lcid, const srsran::rlc_config_t& cnfg) { return SRSRAN_SUCCESS; }
void add_bearer_mrb(uint32_t lcid) {} int add_bearer_mrb(uint32_t lcid) { return SRSRAN_SUCCESS; }
void del_bearer(uint32_t lcid) {} void del_bearer(uint32_t lcid) {}
void suspend_bearer(uint32_t lcid) {} void suspend_bearer(uint32_t lcid) {}
void resume_bearer(uint32_t lcid) {} void resume_bearer(uint32_t lcid) {}

@ -201,7 +201,7 @@ int ue_stack_lte::init(const stack_args_t& args_)
sync_task_queue = task_sched.make_task_queue(args.sync_queue_size); sync_task_queue = task_sched.make_task_queue(args.sync_queue_size);
mac.init(phy, &rlc, &rrc); mac.init(phy, &rlc, &rrc);
rlc.init(&pdcp, &rrc, &rrc_nr, task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */); rlc.init(&pdcp, &rrc, task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */);
pdcp.init(&rlc, &rrc, &rrc_nr, gw); pdcp.init(&rlc, &rrc, &rrc_nr, gw);
nas.init(usim.get(), &rrc, gw, args.nas); nas.init(usim.get(), &rrc, gw, args.nas);

Loading…
Cancel
Save