removed extra threads from enb rrc

master
Francisco Paisana 5 years ago committed by Francisco Paisana
parent 33aa858118
commit 177e880293

@ -30,7 +30,6 @@
#include "srslte/common/common.h" #include "srslte/common/common.h"
#include "srslte/common/log.h" #include "srslte/common/log.h"
#include "srslte/common/stack_procedure.h" #include "srslte/common/stack_procedure.h"
#include "srslte/common/threads.h"
#include "srslte/common/timeout.h" #include "srslte/common/timeout.h"
#include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/enb_interfaces.h"
#include <map> #include <map>
@ -141,8 +140,7 @@ static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE",
class rrc final : public rrc_interface_pdcp, class rrc final : public rrc_interface_pdcp,
public rrc_interface_mac, public rrc_interface_mac,
public rrc_interface_rlc, public rrc_interface_rlc,
public rrc_interface_s1ap, public rrc_interface_s1ap
public thread
{ {
public: public:
rrc(); rrc();
@ -155,10 +153,12 @@ public:
pdcp_interface_rrc* pdcp, pdcp_interface_rrc* pdcp,
s1ap_interface_rrc* s1ap, s1ap_interface_rrc* s1ap,
gtpu_interface_rrc* gtpu, gtpu_interface_rrc* gtpu,
srslte::timer_handler* timers_,
srslte::log* log_rrc); srslte::log* log_rrc);
void stop(); void stop();
void get_metrics(rrc_metrics_t& m); void get_metrics(rrc_metrics_t& m);
void tti_clock();
// rrc_interface_mac // rrc_interface_mac
void rl_failure(uint16_t rnti) override; void rl_failure(uint16_t rnti) override;
@ -200,18 +200,6 @@ public:
}; };
void set_connect_notifer(connect_notifier* cnotifier); void set_connect_notifer(connect_notifier* cnotifier);
class activity_monitor final : public thread
{
public:
explicit activity_monitor(rrc* parent_);
void stop();
private:
rrc* parent;
bool running;
void run_thread() override;
};
class ue class ue
{ {
public: public:
@ -351,11 +339,21 @@ public:
}; };
private: private:
std::map<uint16_t, std::unique_ptr<ue> > users; // NOTE: has to have fixed addr // args
srslte::timer_handler* timers = nullptr;
srslte::byte_buffer_pool* pool = nullptr;
phy_interface_stack_lte* phy = nullptr;
mac_interface_rrc* mac = nullptr;
rlc_interface_rrc* rlc = nullptr;
pdcp_interface_rrc* pdcp = nullptr;
gtpu_interface_rrc* gtpu = nullptr;
s1ap_interface_rrc* s1ap = nullptr;
srslte::log* rrc_log = nullptr;
// state
std::map<uint16_t, std::unique_ptr<ue> > users; // NOTE: has to have fixed addr
std::map<uint32_t, LIBLTE_S1AP_UEPAGINGID_STRUCT> pending_paging; std::map<uint32_t, LIBLTE_S1AP_UEPAGINGID_STRUCT> pending_paging;
srslte::timer_handler::unique_timer activity_monitor_timer;
activity_monitor act_monitor;
std::vector<srslte::unique_byte_buffer_t> sib_buffer; std::vector<srslte::unique_byte_buffer_t> sib_buffer;
@ -368,29 +366,23 @@ private:
uint32_t generate_sibs(); uint32_t generate_sibs();
void configure_mbsfn_sibs(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13); void configure_mbsfn_sibs(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13);
void config_mac(); void config_mac();
void parse_ul_dcch(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu); void parse_ul_dcch(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu);
void parse_ul_ccch(uint16_t rnti, srslte::unique_byte_buffer_t pdu); void parse_ul_ccch(uint16_t rnti, srslte::unique_byte_buffer_t pdu);
void configure_security(uint16_t rnti, void configure_security(uint16_t rnti,
uint32_t lcid, uint32_t lcid,
uint8_t* k_rrc_enc, uint8_t* k_rrc_enc,
uint8_t* k_rrc_int, uint8_t* k_rrc_int,
uint8_t* k_up_enc, uint8_t* k_up_enc,
uint8_t* k_up_int, uint8_t* k_up_int,
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo, srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo); srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo);
void enable_integrity(uint16_t rnti, uint32_t lcid); void enable_integrity(uint16_t rnti, uint32_t lcid);
void enable_encryption(uint16_t rnti, uint32_t lcid); void enable_encryption(uint16_t rnti, uint32_t lcid);
srslte::byte_buffer_pool* pool;
srslte::byte_buffer_t byte_buf_paging; void monitor_activity();
phy_interface_stack_lte* phy; srslte::byte_buffer_t byte_buf_paging;
mac_interface_rrc* mac;
rlc_interface_rrc* rlc;
pdcp_interface_rrc* pdcp;
gtpu_interface_rrc* gtpu;
s1ap_interface_rrc* s1ap;
srslte::log* rrc_log;
typedef struct { typedef struct {
uint16_t rnti; uint16_t rnti;
@ -424,7 +416,6 @@ private:
class mobility_cfg; class mobility_cfg;
std::unique_ptr<mobility_cfg> enb_mobility_cfg; std::unique_ptr<mobility_cfg> enb_mobility_cfg;
void run_thread() override;
void rem_user_thread(uint16_t rnti); void rem_user_thread(uint16_t rnti);
pthread_mutex_t user_mutex; pthread_mutex_t user_mutex;

@ -120,7 +120,7 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_)
mac.init(args.mac, &cell_cfg, phy, &rlc, &rrc, &mac_log); mac.init(args.mac, &cell_cfg, phy, &rlc, &rrc, &mac_log);
rlc.init(&pdcp, &rrc, &mac, &timers, &rlc_log); rlc.init(&pdcp, &rrc, &mac, &timers, &rlc_log);
pdcp.init(&rlc, &rrc, &gtpu); pdcp.init(&rlc, &rrc, &gtpu);
rrc.init(&rrc_cfg, phy, &mac, &rlc, &pdcp, &s1ap, &gtpu, &rrc_log); rrc.init(&rrc_cfg, phy, &mac, &rlc, &pdcp, &s1ap, &gtpu, &timers, &rrc_log);
s1ap.init(args.s1ap, &rrc, &s1ap_log, &timers); s1ap.init(args.s1ap, &rrc, &s1ap_log, &timers);
gtpu.init(args.s1ap.gtp_bind_addr, gtpu.init(args.s1ap.gtp_bind_addr,
args.s1ap.mme_addr, args.s1ap.mme_addr,
@ -148,6 +148,7 @@ void enb_stack_lte::tti_clock_impl()
{ {
timers.step_all(); timers.step_all();
mac.tti_clock(); mac.tti_clock();
rrc.tti_clock();
} }
void enb_stack_lte::stop() void enb_stack_lte::stop()

@ -38,20 +38,11 @@ using namespace asn1::rrc;
namespace srsenb { namespace srsenb {
rrc::rrc() : act_monitor(this), cnotifier(nullptr), nof_si_messages(0), thread("RRC") rrc::rrc() : cnotifier(nullptr), nof_si_messages(0)
{ {
users.clear(); users.clear();
pending_paging.clear(); pending_paging.clear();
pool = nullptr;
phy = nullptr;
mac = nullptr;
rlc = nullptr;
pdcp = nullptr;
gtpu = nullptr;
s1ap = nullptr;
rrc_log = nullptr;
bzero(&sr_sched, sizeof(sr_sched)); bzero(&sr_sched, sizeof(sr_sched));
bzero(&cqi_sched, sizeof(cqi_sched)); bzero(&cqi_sched, sizeof(cqi_sched));
bzero(&cfg.sr_cfg, sizeof(cfg.sr_cfg)); bzero(&cfg.sr_cfg, sizeof(cfg.sr_cfg));
@ -69,6 +60,7 @@ void rrc::init(rrc_cfg_t* cfg_,
pdcp_interface_rrc* pdcp_, pdcp_interface_rrc* pdcp_,
s1ap_interface_rrc* s1ap_, s1ap_interface_rrc* s1ap_,
gtpu_interface_rrc* gtpu_, gtpu_interface_rrc* gtpu_,
srslte::timer_handler* timers_,
srslte::log* log_rrc) srslte::log* log_rrc)
{ {
phy = phy_; phy = phy_;
@ -78,10 +70,10 @@ void rrc::init(rrc_cfg_t* cfg_,
gtpu = gtpu_; gtpu = gtpu_;
s1ap = s1ap_; s1ap = s1ap_;
rrc_log = log_rrc; rrc_log = log_rrc;
timers = timers_;
cnotifier = nullptr; cnotifier = nullptr;
running = false; pool = srslte::byte_buffer_pool::get_instance();
pool = srslte::byte_buffer_pool::get_instance();
cfg = *cfg_; cfg = *cfg_;
@ -97,10 +89,17 @@ void rrc::init(rrc_cfg_t* cfg_,
pthread_mutex_init(&user_mutex, nullptr); pthread_mutex_init(&user_mutex, nullptr);
pthread_mutex_init(&paging_mutex, nullptr); pthread_mutex_init(&paging_mutex, nullptr);
act_monitor.start(RRC_THREAD_PRIO);
bzero(&sr_sched, sizeof(sr_sched_t)); bzero(&sr_sched, sizeof(sr_sched_t));
start(RRC_THREAD_PRIO); // run active monitor timer in a 10ms loop
activity_monitor_timer = timers->get_unique_timer();
activity_monitor_timer.set(10, [this](uint32_t tid) {
monitor_activity();
activity_monitor_timer.run();
});
activity_monitor_timer.run();
running = true;
} }
void rrc::set_connect_notifer(connect_notifier* cnotifier_) void rrc::set_connect_notifer(connect_notifier* cnotifier_)
@ -114,9 +113,7 @@ void rrc::stop()
running = false; running = false;
rrc_pdu p = {0, LCID_EXIT, nullptr}; rrc_pdu p = {0, LCID_EXIT, nullptr};
rx_pdu_queue.push(std::move(p)); rx_pdu_queue.push(std::move(p));
wait_thread_finish();
} }
act_monitor.stop();
pthread_mutex_lock(&user_mutex); pthread_mutex_lock(&user_mutex);
users.clear(); users.clear();
pthread_mutex_unlock(&user_mutex); pthread_mutex_unlock(&user_mutex);
@ -763,7 +760,6 @@ void rrc::process_release_complete(uint16_t rnti)
void rrc::rem_user(uint16_t rnti) void rrc::rem_user(uint16_t rnti)
{ {
pthread_mutex_lock(&user_mutex);
auto user_it = users.find(rnti); auto user_it = users.find(rnti);
if (user_it != users.end()) { if (user_it != users.end()) {
rrc_log->console("Disconnecting rnti=0x%x.\n", rnti); rrc_log->console("Disconnecting rnti=0x%x.\n", rnti);
@ -787,7 +783,6 @@ void rrc::rem_user(uint16_t rnti)
} else { } else {
rrc_log->error("Removing user rnti=0x%x (does not exist)\n", rnti); rrc_log->error("Removing user rnti=0x%x (does not exist)\n", rnti);
} }
pthread_mutex_unlock(&user_mutex);
} }
void rrc::config_mac() void rrc::config_mac()
@ -944,110 +939,97 @@ void rrc::enable_encryption(uint16_t rnti, uint32_t lcid)
pdcp->enable_encryption(rnti, lcid); pdcp->enable_encryption(rnti, lcid);
} }
/******************************************************************************* void rrc::monitor_activity()
RRC thread
*******************************************************************************/
void rrc::run_thread()
{ {
rrc_pdu p; pthread_mutex_lock(&user_mutex);
running = true;
while (running) { uint16_t rem_rnti = 0;
p = rx_pdu_queue.wait_pop(); for (auto& user : users) {
if (p.pdu) { if (user.first == SRSLTE_MRNTI) {
rrc_log->info_hex(p.pdu->msg, p.pdu->N_bytes, "Rx %s PDU", rb_id_text[p.lcid]); continue;
} }
ue* u = (ue*)&user.second;
uint16_t rnti = (uint16_t)user.first;
// Mutex these calls even though it's a private function if (cnotifier && u->is_connected() && !u->connect_notified) {
auto user_it = users.find(p.rnti); cnotifier->user_connected(rnti);
if (user_it != users.end()) { u->connect_notified = true;
switch (p.lcid) { }
case RB_ID_SRB0:
parse_ul_ccch(p.rnti, std::move(p.pdu)); if (u->is_timeout()) {
break; rrc_log->info("User rnti=0x%x timed out. Exists in s1ap=%s\n", rnti, s1ap->user_exists(rnti) ? "yes" : "no");
case RB_ID_SRB1: rem_rnti = rnti;
case RB_ID_SRB2: break;
parse_ul_dcch(p.rnti, p.lcid, std::move(p.pdu)); }
break; }
case LCID_REM_USER: if (rem_rnti > 0) {
rem_user(p.rnti); if (s1ap->user_exists(rem_rnti)) {
break; s1ap->user_release(rem_rnti, LIBLTE_S1AP_CAUSERADIONETWORK_USER_INACTIVITY);
case LCID_REL_USER:
process_release_complete(p.rnti);
break;
case LCID_RLF_USER:
process_rl_failure(p.rnti);
break;
case LCID_ACT_USER:
user_it->second->set_activity();
break;
case LCID_EXIT:
rrc_log->info("Exiting thread\n");
break;
default:
rrc_log->error("Rx PDU with invalid bearer id: %d", p.lcid);
break;
}
} else { } else {
rrc_log->warning("Discarding PDU for removed rnti=0x%x\n", p.rnti); if (rem_rnti != SRSLTE_MRNTI) {
rem_user_thread(rem_rnti);
}
} }
} }
pthread_mutex_unlock(&user_mutex);
} }
/******************************************************************************* /*******************************************************************************
Activity monitor class RRC run tti method
*******************************************************************************/ *******************************************************************************/
rrc::activity_monitor::activity_monitor(rrc* parent_) : thread("RRC_ACTIVITY_MONITOR") void rrc::tti_clock()
{
running = true;
parent = parent_;
}
void rrc::activity_monitor::stop()
{ {
if (running) { pthread_mutex_lock(&user_mutex);
running = false; // pop cmd from queue
thread_cancel(); rrc_pdu p;
wait_thread_finish(); if (not rx_pdu_queue.try_pop(&p)) {
pthread_mutex_unlock(&user_mutex);
return;
}
// print Rx PDU
if (p.pdu != nullptr) {
rrc_log->info_hex(p.pdu->msg, p.pdu->N_bytes, "Rx %s PDU", rb_id_text[p.lcid]);
} }
}
void rrc::activity_monitor::run_thread()
{
while (running) {
usleep(10000);
pthread_mutex_lock(&parent->user_mutex);
uint16_t rem_rnti = 0;
for (auto iter = parent->users.begin(); rem_rnti == 0 && iter != parent->users.end(); ++iter) {
if (iter->first != SRSLTE_MRNTI) {
ue* u = (ue*)&iter->second;
uint16_t rnti = (uint16_t)iter->first;
if (parent->cnotifier && u->is_connected() && !u->connect_notified) { // check if user exists
parent->cnotifier->user_connected(rnti); auto user_it = users.find(p.rnti);
u->connect_notified = true; if (user_it == users.end()) {
} rrc_log->warning("Discarding PDU for removed rnti=0x%x\n", p.rnti);
pthread_mutex_unlock(&user_mutex);
return;
}
if (u->is_timeout()) { // handle queue cmd
parent->rrc_log->info( switch (p.lcid) {
"User rnti=0x%x timed out. Exists in s1ap=%s\n", rnti, parent->s1ap->user_exists(rnti) ? "yes" : "no"); case RB_ID_SRB0:
rem_rnti = rnti; parse_ul_ccch(p.rnti, std::move(p.pdu));
} break;
} case RB_ID_SRB1:
} case RB_ID_SRB2:
if (rem_rnti > 0) { parse_ul_dcch(p.rnti, p.lcid, std::move(p.pdu));
if (parent->s1ap->user_exists(rem_rnti)) { break;
parent->s1ap->user_release(rem_rnti, LIBLTE_S1AP_CAUSERADIONETWORK_USER_INACTIVITY); case LCID_REM_USER:
} else { rem_user(p.rnti);
if (rem_rnti != SRSLTE_MRNTI) { break;
parent->rem_user_thread(rem_rnti); case LCID_REL_USER:
} process_release_complete(p.rnti);
} break;
} case LCID_RLF_USER:
pthread_mutex_unlock(&parent->user_mutex); process_rl_failure(p.rnti);
break;
case LCID_ACT_USER:
user_it->second->set_activity();
break;
case LCID_EXIT:
rrc_log->info("Exiting thread\n");
break;
default:
rrc_log->error("Rx PDU with invalid bearer id: %d", p.lcid);
break;
} }
pthread_mutex_unlock(&user_mutex);
} }
/******************************************************************************* /*******************************************************************************
@ -2226,7 +2208,7 @@ int rrc::ue::sr_allocate(uint32_t period, uint8_t* I_sr, uint16_t* N_pucch_sr)
// Find freq-time resources with least number of users // Find freq-time resources with least number of users
int i_min = 0, j_min = 0; int i_min = 0, j_min = 0;
uint32_t min_users = 1e6; uint32_t min_users = std::numeric_limits<uint32_t>::max();
for (uint32_t i = 0; i < parent->cfg.sr_cfg.nof_prb; i++) { for (uint32_t i = 0; i < parent->cfg.sr_cfg.nof_prb; i++) {
for (uint32_t j = 0; j < parent->cfg.sr_cfg.nof_subframes; j++) { for (uint32_t j = 0; j < parent->cfg.sr_cfg.nof_subframes; j++) {
if (parent->sr_sched.nof_users[i][j] < min_users) { if (parent->sr_sched.nof_users[i][j] < min_users) {
@ -2308,7 +2290,7 @@ int rrc::ue::cqi_allocate(uint32_t period, uint16_t* pmi_idx, uint16_t* n_pucch)
// Find freq-time resources with least number of users // Find freq-time resources with least number of users
int i_min = 0, j_min = 0; int i_min = 0, j_min = 0;
uint32_t min_users = 1e6; uint32_t min_users = std::numeric_limits<uint32_t>::max();
for (uint32_t i = 0; i < parent->cfg.cqi_cfg.nof_prb; i++) { for (uint32_t i = 0; i < parent->cfg.cqi_cfg.nof_prb; i++) {
for (uint32_t j = 0; j < parent->cfg.cqi_cfg.nof_subframes; j++) { for (uint32_t j = 0; j < parent->cfg.cqi_cfg.nof_subframes; j++) {
if (parent->cqi_sched.nof_users[i][j] < min_users) { if (parent->cqi_sched.nof_users[i][j] < min_users) {
@ -2342,7 +2324,7 @@ int rrc::ue::cqi_allocate(uint32_t period, uint16_t* pmi_idx, uint16_t* n_pucch)
*pmi_idx = 318 + parent->cfg.cqi_cfg.sf_mapping[j_min]; *pmi_idx = 318 + parent->cfg.cqi_cfg.sf_mapping[j_min];
} else if (period == 64) { } else if (period == 64) {
*pmi_idx = 350 + parent->cfg.cqi_cfg.sf_mapping[j_min]; *pmi_idx = 350 + parent->cfg.cqi_cfg.sf_mapping[j_min];
} else if (period == 128) { } else {
*pmi_idx = 414 + parent->cfg.cqi_cfg.sf_mapping[j_min]; *pmi_idx = 414 + parent->cfg.cqi_cfg.sf_mapping[j_min];
} }
} }

@ -22,8 +22,6 @@
#ifndef SRSUE_RRC_H #ifndef SRSUE_RRC_H
#define SRSUE_RRC_H #define SRSUE_RRC_H
#include "pthread.h"
#include "rrc_common.h" #include "rrc_common.h"
#include "rrc_metrics.h" #include "rrc_metrics.h"
#include "srslte/asn1/rrc_asn1.h" #include "srslte/asn1/rrc_asn1.h"
@ -35,7 +33,6 @@
#include "srslte/common/log.h" #include "srslte/common/log.h"
#include "srslte/common/security.h" #include "srslte/common/security.h"
#include "srslte/common/stack_procedure.h" #include "srslte/common/stack_procedure.h"
#include "srslte/common/threads.h"
#include "srslte/interfaces/ue_interfaces.h" #include "srslte/interfaces/ue_interfaces.h"
#include <map> #include <map>

Loading…
Cancel
Save