mirror of https://github.com/pvnis/srsRAN_4G.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
4.3 KiB
C++
165 lines
4.3 KiB
C++
/*
|
|
* 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/.
|
|
*
|
|
*/
|
|
|
|
#define Error(fmt, ...) log_h->error(fmt, ##__VA_ARGS__)
|
|
#define Warning(fmt, ...) log_h->warning(fmt, ##__VA_ARGS__)
|
|
#define Info(fmt, ...) log_h->info(fmt, ##__VA_ARGS__)
|
|
#define Debug(fmt, ...) log_h->debug(fmt, ##__VA_ARGS__)
|
|
|
|
#include "srsue/hdr/stack/mac/proc_phr.h"
|
|
#include "srslte/interfaces/ue_interfaces.h"
|
|
#include "srsue/hdr/stack/mac/mac.h"
|
|
#include "srsue/hdr/stack/mac/mux.h"
|
|
|
|
namespace srsue {
|
|
|
|
phr_proc::phr_proc()
|
|
{
|
|
initiated = false;
|
|
last_pathloss_db = 0;
|
|
phr_cfg = {};
|
|
}
|
|
|
|
void phr_proc::init(phy_interface_mac_lte* phy_h_, srslte::log* log_h_, srslte::timer_handler* timers_db_)
|
|
{
|
|
phy_h = phy_h_;
|
|
log_h = log_h_;
|
|
timers_db = timers_db_;
|
|
initiated = true;
|
|
|
|
timer_periodic = timers_db->get_unique_timer();
|
|
timer_prohibit = timers_db->get_unique_timer();
|
|
|
|
reset();
|
|
}
|
|
|
|
void phr_proc::reset()
|
|
{
|
|
timer_periodic.stop();
|
|
timer_prohibit.stop();
|
|
phr_is_triggered = false;
|
|
}
|
|
|
|
void phr_proc::set_config(srslte::phr_cfg_t& cfg)
|
|
{
|
|
phr_cfg = cfg;
|
|
|
|
// First stop timers. If enabled==false or value is Inf, won't be re-started
|
|
timer_periodic.stop();
|
|
timer_prohibit.stop();
|
|
|
|
if (cfg.enabled) {
|
|
// Setup timers and trigger PHR when configuration changed by higher layers
|
|
if (phr_cfg.periodic_timer > 0) {
|
|
timer_periodic.set(phr_cfg.periodic_timer, [this](uint32_t tid) { timer_expired(tid); });
|
|
timer_periodic.run();
|
|
phr_is_triggered = true;
|
|
Info("PHR: Configured timer periodic %d ms\n", phr_cfg.periodic_timer);
|
|
}
|
|
|
|
if (phr_cfg.prohibit_timer > 0) {
|
|
timer_prohibit.set(phr_cfg.prohibit_timer, [this](uint32_t tid) { timer_expired(tid); });
|
|
timer_prohibit.run();
|
|
Info("PHR: Configured timer prohibit %d ms\n", phr_cfg.prohibit_timer);
|
|
phr_is_triggered = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool phr_proc::pathloss_changed()
|
|
{
|
|
if (!phr_cfg.enabled) {
|
|
return false;
|
|
}
|
|
|
|
int cur_pathloss_db = (int)phy_h->get_pathloss_db();
|
|
|
|
if (abs(cur_pathloss_db - last_pathloss_db) > phr_cfg.db_pathloss_change && phr_cfg.db_pathloss_change > 0) {
|
|
last_pathloss_db = cur_pathloss_db;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void phr_proc::start_timer()
|
|
{
|
|
timer_periodic.run();
|
|
}
|
|
|
|
/* Trigger PHR when timers exires */
|
|
void phr_proc::timer_expired(uint32_t timer_id)
|
|
{
|
|
if (!phr_cfg.enabled) {
|
|
Warning("PHR: Timer triggered but PHR has been disabled\n");
|
|
return;
|
|
}
|
|
if (timer_id == timer_periodic.id()) {
|
|
timer_periodic.run();
|
|
Debug("PHR: Triggered by timer periodic (timer expired).\n");
|
|
phr_is_triggered = true;
|
|
} else if (timer_id == timer_prohibit.id()) {
|
|
if (pathloss_changed()) {
|
|
Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d (timer expired)\n", last_pathloss_db);
|
|
phr_is_triggered = true;
|
|
}
|
|
} else {
|
|
log_h->warning("Received timer callback from unknown timer_id=%d\n", timer_id);
|
|
}
|
|
}
|
|
|
|
void phr_proc::step(uint32_t tti)
|
|
{
|
|
if (phr_cfg.enabled && initiated) {
|
|
if (pathloss_changed() && timer_prohibit.is_expired()) {
|
|
Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d\n", last_pathloss_db);
|
|
phr_is_triggered = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool phr_proc::generate_phr_on_ul_grant(float* phr)
|
|
{
|
|
|
|
if (phr_is_triggered) {
|
|
if (phr) {
|
|
*phr = phy_h->get_phr();
|
|
}
|
|
|
|
Debug("PHR: Generating PHR=%f\n", phr ? *phr : 0.0);
|
|
|
|
timer_periodic.run();
|
|
timer_prohibit.run();
|
|
|
|
phr_is_triggered = false;
|
|
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool phr_proc::is_extended()
|
|
{
|
|
return phr_cfg.extended;
|
|
}
|
|
} // namespace srsue
|