mirror of https://github.com/PentHertz/srsLTE.git
Merge pull request #662 from softwareradiosystems/pr_new_timer
new timer class
This commit is contained in:
commit
1c375d99e0
|
@ -102,17 +102,6 @@ public:
|
||||||
// bool do_rohc;
|
// bool do_rohc;
|
||||||
};
|
};
|
||||||
|
|
||||||
class mac_interface_timers
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/* Timer services with ms resolution.
|
|
||||||
* timer_id must be lower than MAC_NOF_UPPER_TIMERS
|
|
||||||
*/
|
|
||||||
virtual timers::timer* timer_get(uint32_t timer_id) = 0;
|
|
||||||
virtual void timer_release_id(uint32_t timer_id) = 0;
|
|
||||||
virtual uint32_t timer_get_unique_id() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class read_pdu_interface
|
class read_pdu_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -29,10 +29,14 @@
|
||||||
#ifndef SRSLTE_TIMERS_H
|
#ifndef SRSLTE_TIMERS_H
|
||||||
#define SRSLTE_TIMERS_H
|
#define SRSLTE_TIMERS_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <limits>
|
||||||
|
#include <queue>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "srslte/srslte.h"
|
#include "srslte/srslte.h"
|
||||||
|
|
||||||
|
@ -40,133 +44,249 @@ namespace srslte {
|
||||||
|
|
||||||
class timer_callback
|
class timer_callback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void timer_expired(uint32_t timer_id) = 0;
|
virtual void timer_expired(uint32_t timer_id) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class timers
|
class timer_handler
|
||||||
{
|
{
|
||||||
public:
|
constexpr static uint32_t MAX_TIMER_DURATION = std::numeric_limits<uint32_t>::max() / 4;
|
||||||
class timer
|
constexpr static uint32_t MAX_TIMER_VALUE = std::numeric_limits<uint32_t>::max() / 2;
|
||||||
{
|
|
||||||
public:
|
struct timer_impl {
|
||||||
timer(uint32_t id_=0) {id = id_; counter = 0; timeout = 0; running = false; callback = NULL; }
|
timer_handler* parent;
|
||||||
void set(timer_callback *callback_, uint32_t timeout_) {
|
uint32_t duration = 0, timeout = 0;
|
||||||
callback = callback_;
|
bool running = false;
|
||||||
timeout = timeout_;
|
bool active = false;
|
||||||
reset();
|
std::function<void(uint32_t)> callback;
|
||||||
}
|
|
||||||
bool is_running() {
|
explicit timer_impl(timer_handler* parent_) : parent(parent_) {}
|
||||||
return (counter < timeout) && running;
|
|
||||||
}
|
uint32_t id() const { return std::distance((const timer_handler::timer_impl*)&parent->timer_list[0], this); }
|
||||||
bool is_expired() {
|
|
||||||
return (timeout > 0) && (counter >= timeout);
|
bool is_running() const { return active and running and timeout > 0; }
|
||||||
}
|
|
||||||
uint32_t get_timeout() {
|
bool is_expired() const { return active and not running and timeout > 0 and timeout <= parent->cur_time; }
|
||||||
return timeout;
|
|
||||||
}
|
uint32_t value() const { return parent->cur_time - (timeout - duration); }
|
||||||
void reset() {
|
|
||||||
counter = 0;
|
bool set(uint32_t duration_)
|
||||||
}
|
{
|
||||||
uint32_t value() {
|
if (duration_ > MAX_TIMER_DURATION) {
|
||||||
return counter;
|
ERROR("Error: timer durations above %u are not supported\n", MAX_TIMER_DURATION);
|
||||||
}
|
return false;
|
||||||
void step() {
|
|
||||||
if (running) {
|
|
||||||
counter++;
|
|
||||||
if (is_expired()) {
|
|
||||||
running = false;
|
|
||||||
if (callback) {
|
|
||||||
callback->timer_expired(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (not active) {
|
||||||
|
ERROR("Error: setting inactive timer id=%d\n", id());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
duration = duration_;
|
||||||
|
if (is_running()) {
|
||||||
|
// if already running, just extends timer lifetime
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
void stop() {
|
|
||||||
running = false;
|
bool set(uint32_t duration_, std::function<void(int)> callback_)
|
||||||
|
{
|
||||||
|
if (set(duration_)) {
|
||||||
|
callback = std::move(callback_);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
void run() {
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
if (not active) {
|
||||||
|
ERROR("Error: calling run() for inactive timer id=%d\n", id());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
timeout = parent->cur_time + duration;
|
||||||
|
parent->running_timers.emplace(id(), timeout);
|
||||||
running = true;
|
running = true;
|
||||||
}
|
}
|
||||||
uint32_t id;
|
|
||||||
private:
|
void stop()
|
||||||
timer_callback *callback;
|
{
|
||||||
uint32_t timeout;
|
running = false; // invalidates trigger
|
||||||
uint32_t counter;
|
if (not is_expired()) {
|
||||||
bool running;
|
timeout = 0; // if it has already expired, then do not alter is_expired() state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
duration = 0;
|
||||||
|
active = false;
|
||||||
|
callback = std::function<void(uint32_t)>();
|
||||||
|
// leave run_id unchanged. Since the timeout was changed, we shall not get spurious triggering
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger()
|
||||||
|
{
|
||||||
|
if (is_running()) {
|
||||||
|
if (callback) {
|
||||||
|
callback(id());
|
||||||
|
}
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
timers(uint32_t nof_timers_) : timer_list(nof_timers_), used_timers(nof_timers_)
|
public:
|
||||||
|
class unique_timer
|
||||||
{
|
{
|
||||||
nof_timers = nof_timers_;
|
public:
|
||||||
next_timer = 0;
|
unique_timer() : parent(nullptr), timer_id(std::numeric_limits<decltype(timer_id)>::max()) {}
|
||||||
nof_used_timers = 0;
|
explicit unique_timer(timer_handler* parent_, uint32_t timer_id_) : parent(parent_), timer_id(timer_id_) {}
|
||||||
for (uint32_t i = 0; i < nof_timers; i++) {
|
|
||||||
timer_list[i].id = i;
|
unique_timer(const unique_timer&) = delete;
|
||||||
used_timers[i] = false;
|
|
||||||
|
unique_timer(unique_timer&& other) noexcept : parent(other.parent), timer_id(other.timer_id)
|
||||||
|
{
|
||||||
|
other.parent = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
~unique_timer()
|
||||||
|
{
|
||||||
|
if (parent) {
|
||||||
|
// does not call callback
|
||||||
|
impl()->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_timer& operator=(const unique_timer&) = delete;
|
||||||
|
|
||||||
|
unique_timer& operator=(unique_timer&& other) noexcept
|
||||||
|
{
|
||||||
|
if (this != &other) {
|
||||||
|
timer_id = other.timer_id;
|
||||||
|
parent = other.parent;
|
||||||
|
other.parent = nullptr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_valid() const { return parent != nullptr; }
|
||||||
|
|
||||||
|
void set(uint32_t duration_, const std::function<void(int)>& callback_) { impl()->set(duration_, callback_); }
|
||||||
|
|
||||||
|
void set(uint32_t duration_) { impl()->set(duration_); }
|
||||||
|
|
||||||
|
bool is_running() const { return impl()->is_running(); }
|
||||||
|
|
||||||
|
bool is_expired() const { return impl()->is_expired(); }
|
||||||
|
|
||||||
|
uint32_t value() const { return impl()->value(); }
|
||||||
|
|
||||||
|
void run() { impl()->run(); }
|
||||||
|
|
||||||
|
void stop() { impl()->stop(); }
|
||||||
|
|
||||||
|
void release()
|
||||||
|
{
|
||||||
|
impl()->clear();
|
||||||
|
parent = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t id() const { return timer_id; }
|
||||||
|
|
||||||
|
uint32_t duration() const { return impl()->duration; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
timer_impl* impl() { return &parent->timer_list[timer_id]; }
|
||||||
|
|
||||||
|
const timer_impl* impl() const { return &parent->timer_list[timer_id]; }
|
||||||
|
|
||||||
|
timer_handler* parent;
|
||||||
|
uint32_t timer_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit timer_handler(uint32_t capacity = 64)
|
||||||
|
{
|
||||||
|
timer_list.reserve(capacity);
|
||||||
|
// reserve a priority queue using a vector
|
||||||
|
std::vector<timer_run> v;
|
||||||
|
v.reserve(capacity);
|
||||||
|
std::priority_queue<timer_run> q(std::less<timer_run>(), std::move(v));
|
||||||
|
running_timers = std::move(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
void step_all()
|
||||||
|
{
|
||||||
|
cur_time++;
|
||||||
|
while (not running_timers.empty() and cur_time >= running_timers.top().timeout) {
|
||||||
|
timer_impl* ptr = &timer_list[running_timers.top().timer_id];
|
||||||
|
// if the timer_run and timer_impl timeouts do not match, it means that timer_impl::timeout was overwritten.
|
||||||
|
// in such case, do not trigger
|
||||||
|
if (ptr->timeout == running_timers.top().timeout) {
|
||||||
|
ptr->trigger();
|
||||||
|
}
|
||||||
|
running_timers.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void step_all() {
|
void stop_all()
|
||||||
for (uint32_t i=0;i<nof_timers;i++) {
|
{
|
||||||
get(i)->step();
|
// does not call callback
|
||||||
|
while (not running_timers.empty()) {
|
||||||
|
running_timers.pop();
|
||||||
|
}
|
||||||
|
for (auto& i : timer_list) {
|
||||||
|
i.running = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void stop_all() {
|
|
||||||
for (uint32_t i=0;i<nof_timers;i++) {
|
unique_timer get_unique_timer()
|
||||||
get(i)->stop();
|
{
|
||||||
}
|
uint32_t i = 0;
|
||||||
}
|
for (; i < timer_list.size(); ++i) {
|
||||||
void run_all() {
|
if (not timer_list[i].active) {
|
||||||
for (uint32_t i=0;i<nof_timers;i++) {
|
break;
|
||||||
get(i)->run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void reset_all() {
|
|
||||||
for (uint32_t i=0;i<nof_timers;i++) {
|
|
||||||
get(i)->reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
timer *get(uint32_t i) {
|
|
||||||
if (i < nof_timers) {
|
|
||||||
return &timer_list[i];
|
|
||||||
} else {
|
|
||||||
printf("Error accessing invalid timer %d (Only %d timers available)\n", i, nof_timers);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void release_id(uint32_t i) {
|
|
||||||
if (nof_used_timers > 0 && i < nof_timers) {
|
|
||||||
used_timers[i] = false;
|
|
||||||
nof_used_timers--;
|
|
||||||
} else {
|
|
||||||
ERROR("Error releasing timer id=%d: nof_used_timers=%d, nof_timers=%d\n", i, nof_used_timers, nof_timers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint32_t get_unique_id() {
|
|
||||||
if (nof_used_timers >= nof_timers) {
|
|
||||||
ERROR("Error getting unique timer id: no more timers available\n");
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
for (uint32_t i=0;i<nof_timers;i++) {
|
|
||||||
if (!used_timers[i]) {
|
|
||||||
used_timers[i] = true;
|
|
||||||
nof_used_timers++;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ERROR("Error getting unique timer id: no more timers available but nof_used_timers=%d, nof_timers=%d\n",
|
|
||||||
nof_used_timers,
|
|
||||||
nof_timers);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
if (i == timer_list.size()) {
|
||||||
|
timer_list.emplace_back(this);
|
||||||
|
}
|
||||||
|
timer_list[i].active = true;
|
||||||
|
return unique_timer(this, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t get_cur_time() const { return cur_time; }
|
||||||
|
|
||||||
|
uint32_t nof_timers() const
|
||||||
|
{
|
||||||
|
return std::count_if(timer_list.begin(), timer_list.end(), [](const timer_impl& t) { return t.active; });
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t nof_running_timers() const
|
||||||
|
{
|
||||||
|
return std::count_if(timer_list.begin(), timer_list.end(), [](const timer_impl& t) { return t.is_running(); });
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t next_timer;
|
struct timer_run {
|
||||||
uint32_t nof_used_timers;
|
uint32_t timer_id;
|
||||||
uint32_t nof_timers;
|
uint32_t timeout;
|
||||||
std::vector<timer> timer_list;
|
|
||||||
std::vector<bool> used_timers;
|
timer_run(uint32_t timer_id_, uint32_t timeout_) : timer_id(timer_id_), timeout(timeout_) {}
|
||||||
|
|
||||||
|
bool operator<(const timer_run& other) const
|
||||||
|
{
|
||||||
|
// returns true, if other.timeout is lower than timeout, accounting for wrap around
|
||||||
|
if (timeout > other.timeout) {
|
||||||
|
return (timeout - other.timeout) < MAX_TIMER_VALUE / 2;
|
||||||
|
}
|
||||||
|
return (other.timeout - timeout) > MAX_TIMER_VALUE / 2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<timer_impl> timer_list;
|
||||||
|
std::priority_queue<timer_run> running_timers;
|
||||||
|
uint32_t cur_time = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace srslte
|
} // namespace srslte
|
||||||
|
|
|
@ -45,7 +45,10 @@ class rlc
|
||||||
public:
|
public:
|
||||||
rlc(log* rlc_log_);
|
rlc(log* rlc_log_);
|
||||||
virtual ~rlc();
|
virtual ~rlc();
|
||||||
void init(srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_, srslte::timers* timers_, uint32_t lcid_);
|
void init(srsue::pdcp_interface_rlc* pdcp_,
|
||||||
|
srsue::rrc_interface_rlc* rrc_,
|
||||||
|
srslte::timer_handler* timers_,
|
||||||
|
uint32_t lcid_);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void get_metrics(rlc_metrics_t& m);
|
void get_metrics(rlc_metrics_t& m);
|
||||||
|
@ -85,11 +88,11 @@ public:
|
||||||
private:
|
private:
|
||||||
void reset_metrics();
|
void reset_metrics();
|
||||||
|
|
||||||
byte_buffer_pool* pool = nullptr;
|
byte_buffer_pool* pool = nullptr;
|
||||||
srslte::log* rlc_log = nullptr;
|
srslte::log* rlc_log = 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;
|
||||||
srslte::timers* timers = nullptr;
|
srslte::timer_handler* timers = nullptr;
|
||||||
|
|
||||||
typedef std::map<uint16_t, rlc_common*> rlc_map_t;
|
typedef std::map<uint16_t, rlc_common*> rlc_map_t;
|
||||||
typedef std::pair<uint16_t, rlc_common*> rlc_map_pair_t;
|
typedef std::pair<uint16_t, rlc_common*> rlc_map_pair_t;
|
||||||
|
|
|
@ -68,7 +68,7 @@ public:
|
||||||
uint32_t lcid_,
|
uint32_t lcid_,
|
||||||
srsue::pdcp_interface_rlc* pdcp_,
|
srsue::pdcp_interface_rlc* pdcp_,
|
||||||
srsue::rrc_interface_rlc* rrc_,
|
srsue::rrc_interface_rlc* rrc_,
|
||||||
srslte::timers* timers_);
|
srslte::timer_handler* timers_);
|
||||||
bool configure(rlc_config_t cfg_);
|
bool configure(rlc_config_t cfg_);
|
||||||
void reestablish();
|
void reestablish();
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -176,18 +176,15 @@ private:
|
||||||
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
|
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
srslte::timers::timer* poll_retx_timer = nullptr;
|
srslte::timer_handler::unique_timer poll_retx_timer;
|
||||||
uint32_t poll_retx_timer_id = 0;
|
srslte::timer_handler::unique_timer status_prohibit_timer;
|
||||||
|
|
||||||
srslte::timers::timer* status_prohibit_timer = nullptr;
|
|
||||||
uint32_t status_prohibit_timer_id = 0;
|
|
||||||
|
|
||||||
// Tx windows
|
// Tx windows
|
||||||
std::map<uint32_t, rlc_amd_tx_pdu_t> tx_window;
|
std::map<uint32_t, rlc_amd_tx_pdu_t> tx_window;
|
||||||
std::deque<rlc_amd_retx_t> retx_queue;
|
std::deque<rlc_amd_retx_t> retx_queue;
|
||||||
|
|
||||||
// Mutexes
|
// Mutexes
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
|
||||||
// Metrics
|
// Metrics
|
||||||
uint32_t num_tx_bytes = 0;
|
uint32_t num_tx_bytes = 0;
|
||||||
|
@ -270,15 +267,14 @@ private:
|
||||||
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
|
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
srslte::timers::timer* reordering_timer = nullptr;
|
srslte::timer_handler::unique_timer reordering_timer;
|
||||||
uint32_t reordering_timer_id = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Common variables needed/provided by parent class
|
// Common variables needed/provided by parent class
|
||||||
srsue::rrc_interface_rlc* rrc = nullptr;
|
srsue::rrc_interface_rlc* rrc = nullptr;
|
||||||
srslte::log* log = nullptr;
|
srslte::log* log = nullptr;
|
||||||
srsue::pdcp_interface_rlc* pdcp = nullptr;
|
srsue::pdcp_interface_rlc* pdcp = nullptr;
|
||||||
srslte::timers* timers = nullptr;
|
srslte::timer_handler* timers = nullptr;
|
||||||
uint32_t lcid = 0;
|
uint32_t lcid = 0;
|
||||||
rlc_config_t cfg = {};
|
rlc_config_t cfg = {};
|
||||||
std::string rb_name;
|
std::string rb_name;
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
uint32_t lcid_,
|
uint32_t lcid_,
|
||||||
srsue::pdcp_interface_rlc* pdcp_,
|
srsue::pdcp_interface_rlc* pdcp_,
|
||||||
srsue::rrc_interface_rlc* rrc_,
|
srsue::rrc_interface_rlc* rrc_,
|
||||||
srslte::timers* timers_,
|
srslte::timer_handler* timers_,
|
||||||
uint32_t queue_len = 16);
|
uint32_t queue_len = 16);
|
||||||
~rlc_tm();
|
~rlc_tm();
|
||||||
bool configure(rlc_config_t cnfg);
|
bool configure(rlc_config_t cnfg);
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
uint32_t lcid_,
|
uint32_t lcid_,
|
||||||
srsue::pdcp_interface_rlc* pdcp_,
|
srsue::pdcp_interface_rlc* pdcp_,
|
||||||
srsue::rrc_interface_rlc* rrc_,
|
srsue::rrc_interface_rlc* rrc_,
|
||||||
srslte::timers* timers_);
|
srslte::timer_handler* timers_);
|
||||||
~rlc_um();
|
~rlc_um();
|
||||||
bool configure(rlc_config_t cnfg);
|
bool configure(rlc_config_t cnfg);
|
||||||
void reestablish();
|
void reestablish();
|
||||||
|
@ -167,7 +167,7 @@ private:
|
||||||
uint32_t lcid_,
|
uint32_t lcid_,
|
||||||
srsue::pdcp_interface_rlc* pdcp_,
|
srsue::pdcp_interface_rlc* pdcp_,
|
||||||
srsue::rrc_interface_rlc* rrc_,
|
srsue::rrc_interface_rlc* rrc_,
|
||||||
srslte::timers* timers_);
|
srslte::timer_handler* timers_);
|
||||||
~rlc_um_rx();
|
~rlc_um_rx();
|
||||||
void stop();
|
void stop();
|
||||||
void reestablish();
|
void reestablish();
|
||||||
|
@ -185,10 +185,10 @@ private:
|
||||||
private:
|
private:
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
byte_buffer_pool* pool = nullptr;
|
byte_buffer_pool* pool = nullptr;
|
||||||
srslte::log* log = nullptr;
|
srslte::log* log = nullptr;
|
||||||
srslte::timers* timers = nullptr;
|
srslte::timer_handler* timers = nullptr;
|
||||||
std::string rb_name;
|
std::string rb_name;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Configurable parameters
|
* Configurable parameters
|
||||||
|
@ -225,11 +225,10 @@ private:
|
||||||
* Timers
|
* Timers
|
||||||
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
|
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
srslte::timers::timer* reordering_timer = nullptr;
|
srslte::timer_handler::unique_timer reordering_timer;
|
||||||
uint32_t reordering_timer_id = 0;
|
|
||||||
|
|
||||||
// helper functions
|
// helper functions
|
||||||
void debug_state();
|
void debug_state();
|
||||||
const char* get_rb_name();
|
const char* get_rb_name();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ rlc::~rlc()
|
||||||
|
|
||||||
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_,
|
||||||
srslte::timers* timers_,
|
srslte::timer_handler* timers_,
|
||||||
uint32_t lcid_)
|
uint32_t lcid_)
|
||||||
{
|
{
|
||||||
pdcp = pdcp_;
|
pdcp = pdcp_;
|
||||||
|
|
|
@ -36,7 +36,7 @@ rlc_am::rlc_am(srslte::log* log_,
|
||||||
uint32_t lcid_,
|
uint32_t lcid_,
|
||||||
srsue::pdcp_interface_rlc* pdcp_,
|
srsue::pdcp_interface_rlc* pdcp_,
|
||||||
srsue::rrc_interface_rlc* rrc_,
|
srsue::rrc_interface_rlc* rrc_,
|
||||||
srslte::timers* timers_) :
|
srslte::timer_handler* timers_) :
|
||||||
log(log_),
|
log(log_),
|
||||||
rrc(rrc_),
|
rrc(rrc_),
|
||||||
pdcp(pdcp_),
|
pdcp(pdcp_),
|
||||||
|
@ -164,25 +164,15 @@ void rlc_am::write_pdu(uint8_t *payload, uint32_t nof_bytes)
|
||||||
rlc_am::rlc_am_tx::rlc_am_tx(rlc_am* parent_) :
|
rlc_am::rlc_am_tx::rlc_am_tx(rlc_am* parent_) :
|
||||||
parent(parent_),
|
parent(parent_),
|
||||||
log(parent_->log),
|
log(parent_->log),
|
||||||
pool(byte_buffer_pool::get_instance())
|
pool(byte_buffer_pool::get_instance()),
|
||||||
|
poll_retx_timer(parent_->timers->get_unique_timer()),
|
||||||
|
status_prohibit_timer(parent_->timers->get_unique_timer())
|
||||||
{
|
{
|
||||||
poll_retx_timer_id = parent->timers->get_unique_id();
|
|
||||||
poll_retx_timer = parent->timers->get(poll_retx_timer_id);
|
|
||||||
|
|
||||||
status_prohibit_timer_id = parent->timers->get_unique_id();
|
|
||||||
status_prohibit_timer = parent->timers->get(status_prohibit_timer_id);
|
|
||||||
|
|
||||||
pthread_mutex_init(&mutex, NULL);
|
pthread_mutex_init(&mutex, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
rlc_am::rlc_am_tx::~rlc_am_tx()
|
rlc_am::rlc_am_tx::~rlc_am_tx()
|
||||||
{
|
{
|
||||||
poll_retx_timer->stop();
|
|
||||||
parent->timers->release_id(poll_retx_timer_id);
|
|
||||||
|
|
||||||
status_prohibit_timer->stop();
|
|
||||||
parent->timers->release_id(status_prohibit_timer_id);
|
|
||||||
|
|
||||||
pthread_mutex_destroy(&mutex);
|
pthread_mutex_destroy(&mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,18 +182,19 @@ bool rlc_am::rlc_am_tx::configure(rlc_config_t cfg_)
|
||||||
cfg = cfg_.am;
|
cfg = cfg_.am;
|
||||||
|
|
||||||
// check timers
|
// check timers
|
||||||
if (poll_retx_timer == NULL or status_prohibit_timer == NULL) {
|
if (not poll_retx_timer.is_valid() or not status_prohibit_timer.is_valid()) {
|
||||||
log->error("Configuring RLC AM TX: timers not configured\n");
|
log->error("Configuring RLC AM TX: timers not configured\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure timers
|
// configure timers
|
||||||
if (cfg.t_status_prohibit > 0) {
|
if (cfg.t_status_prohibit > 0) {
|
||||||
status_prohibit_timer->set(this, static_cast<uint32_t>(cfg.t_status_prohibit));
|
status_prohibit_timer.set(static_cast<uint32_t>(cfg.t_status_prohibit),
|
||||||
|
[this](uint32_t timerid) { timer_expired(timerid); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg.t_poll_retx > 0) {
|
if (cfg.t_poll_retx > 0) {
|
||||||
poll_retx_timer->set(this, static_cast<uint32_t>(cfg.t_poll_retx));
|
poll_retx_timer.set(static_cast<uint32_t>(cfg.t_poll_retx), [this](uint32_t timerid) { timer_expired(timerid); });
|
||||||
}
|
}
|
||||||
|
|
||||||
tx_sdu_queue.resize(cfg_.tx_queue_length);
|
tx_sdu_queue.resize(cfg_.tx_queue_length);
|
||||||
|
@ -221,12 +212,12 @@ void rlc_am::rlc_am_tx::stop()
|
||||||
|
|
||||||
tx_enabled = false;
|
tx_enabled = false;
|
||||||
|
|
||||||
if (parent->timers != NULL && poll_retx_timer != NULL) {
|
if (parent->timers != nullptr && poll_retx_timer.is_valid()) {
|
||||||
poll_retx_timer->stop();
|
poll_retx_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent->timers != NULL && status_prohibit_timer != NULL) {
|
if (parent->timers != nullptr && status_prohibit_timer.is_valid()) {
|
||||||
status_prohibit_timer->stop();
|
status_prohibit_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
vt_a = 0;
|
vt_a = 0;
|
||||||
|
@ -274,9 +265,9 @@ bool rlc_am::rlc_am_tx::do_status()
|
||||||
// Function is supposed to return as fast as possible
|
// Function is supposed to return as fast as possible
|
||||||
bool rlc_am::rlc_am_tx::has_data()
|
bool rlc_am::rlc_am_tx::has_data()
|
||||||
{
|
{
|
||||||
return (((do_status() && not status_prohibit_timer->is_running())) || // if we have a status PDU to transmit
|
return (((do_status() && not status_prohibit_timer.is_running())) || // if we have a status PDU to transmit
|
||||||
(not retx_queue.empty()) || // if we have a retransmission
|
(not retx_queue.empty()) || // if we have a retransmission
|
||||||
(tx_sdu != NULL) || // if we are currently transmitting a SDU
|
(tx_sdu != NULL) || // if we are currently transmitting a SDU
|
||||||
(not tx_sdu_queue.is_empty())); // or if there is a SDU queued up for transmission
|
(not tx_sdu_queue.is_empty())); // or if there is a SDU queued up for transmission
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,11 +280,11 @@ uint32_t rlc_am::rlc_am_tx::get_buffer_state()
|
||||||
log->debug("%s Buffer state - do_status=%d, status_prohibit=%d, timer=%s\n",
|
log->debug("%s Buffer state - do_status=%d, status_prohibit=%d, timer=%s\n",
|
||||||
RB_NAME,
|
RB_NAME,
|
||||||
do_status(),
|
do_status(),
|
||||||
status_prohibit_timer->is_running(),
|
status_prohibit_timer.is_running(),
|
||||||
status_prohibit_timer ? "yes" : "no");
|
status_prohibit_timer.is_valid() ? "yes" : "no");
|
||||||
|
|
||||||
// Bytes needed for status report
|
// Bytes needed for status report
|
||||||
if (do_status() && not status_prohibit_timer->is_running()) {
|
if (do_status() && not status_prohibit_timer.is_running()) {
|
||||||
n_bytes += parent->rx.get_status_pdu_length();
|
n_bytes += parent->rx.get_status_pdu_length();
|
||||||
log->debug("%s Buffer state - total status report: %d bytes\n", RB_NAME, n_bytes);
|
log->debug("%s Buffer state - total status report: %d bytes\n", RB_NAME, n_bytes);
|
||||||
}
|
}
|
||||||
|
@ -393,7 +384,7 @@ int rlc_am::rlc_am_tx::read_pdu(uint8_t *payload, uint32_t nof_bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tx STATUS if requested
|
// Tx STATUS if requested
|
||||||
if (do_status() && not status_prohibit_timer->is_running()) {
|
if (do_status() && not status_prohibit_timer.is_running()) {
|
||||||
pdu_size = build_status_pdu(payload, nof_bytes);
|
pdu_size = build_status_pdu(payload, nof_bytes);
|
||||||
goto unlock_and_exit;
|
goto unlock_and_exit;
|
||||||
}
|
}
|
||||||
|
@ -423,8 +414,8 @@ unlock_and_exit:
|
||||||
void rlc_am::rlc_am_tx::timer_expired(uint32_t timeout_id)
|
void rlc_am::rlc_am_tx::timer_expired(uint32_t timeout_id)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
if (poll_retx_timer != NULL && poll_retx_timer_id == timeout_id) {
|
if (poll_retx_timer.is_valid() && poll_retx_timer.id() == timeout_id) {
|
||||||
log->debug("Poll reTx timer expired for LCID=%d after %d ms\n", parent->lcid, poll_retx_timer->get_timeout());
|
log->debug("Poll reTx timer expired for LCID=%d after %d ms\n", parent->lcid, poll_retx_timer.duration());
|
||||||
// Section 5.2.2.3 in TS 36.311, schedule random PDU for retransmission if
|
// Section 5.2.2.3 in TS 36.311, schedule random PDU for retransmission if
|
||||||
// (a) both tx and retx buffer are empty, or
|
// (a) both tx and retx buffer are empty, or
|
||||||
// (b) no new data PDU can be transmitted (tx window is full)
|
// (b) no new data PDU can be transmitted (tx window is full)
|
||||||
|
@ -477,11 +468,10 @@ bool rlc_am::rlc_am_tx::poll_required()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (poll_retx_timer != NULL) {
|
if (poll_retx_timer.is_valid()) {
|
||||||
if (poll_retx_timer->is_expired()) {
|
if (poll_retx_timer.is_expired()) {
|
||||||
// re-arm timer (will be stopped when status PDU is received)
|
// re-arm timer (will be stopped when status PDU is received)
|
||||||
poll_retx_timer->reset();
|
poll_retx_timer.run();
|
||||||
poll_retx_timer->run();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,19 +501,17 @@ int rlc_am::rlc_am_tx::build_status_pdu(uint8_t *payload, uint32_t nof_bytes)
|
||||||
int pdu_len = parent->rx.get_status_pdu(&tx_status, nof_bytes);
|
int pdu_len = parent->rx.get_status_pdu(&tx_status, nof_bytes);
|
||||||
log->debug("%s\n", rlc_am_status_pdu_to_string(&tx_status).c_str());
|
log->debug("%s\n", rlc_am_status_pdu_to_string(&tx_status).c_str());
|
||||||
if (pdu_len > 0 && nof_bytes >= static_cast<uint32_t>(pdu_len)) {
|
if (pdu_len > 0 && nof_bytes >= static_cast<uint32_t>(pdu_len)) {
|
||||||
log->info("%s Tx status PDU - %s\n",
|
log->info("%s Tx status PDU - %s\n", RB_NAME, rlc_am_status_pdu_to_string(&tx_status).c_str());
|
||||||
RB_NAME, rlc_am_status_pdu_to_string(&tx_status).c_str());
|
|
||||||
|
|
||||||
parent->rx.reset_status();
|
parent->rx.reset_status();
|
||||||
|
|
||||||
if (cfg.t_status_prohibit > 0 && status_prohibit_timer != NULL) {
|
if (cfg.t_status_prohibit > 0 && status_prohibit_timer.is_valid()) {
|
||||||
// re-arm timer
|
// re-arm timer
|
||||||
status_prohibit_timer->reset();
|
status_prohibit_timer.run();
|
||||||
status_prohibit_timer->run();
|
|
||||||
}
|
}
|
||||||
debug_state();
|
debug_state();
|
||||||
pdu_len = rlc_am_write_status_pdu(&tx_status, payload);
|
pdu_len = rlc_am_write_status_pdu(&tx_status, payload);
|
||||||
} else{
|
} else {
|
||||||
log->info("%s Cannot tx status PDU - %d bytes available, %d bytes required\n", RB_NAME, nof_bytes, pdu_len);
|
log->info("%s Cannot tx status PDU - %d bytes available, %d bytes required\n", RB_NAME, nof_bytes, pdu_len);
|
||||||
pdu_len = 0;
|
pdu_len = 0;
|
||||||
}
|
}
|
||||||
|
@ -579,13 +567,12 @@ int rlc_am::rlc_am_tx::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes)
|
||||||
poll_sn = vt_s;
|
poll_sn = vt_s;
|
||||||
pdu_without_poll = 0;
|
pdu_without_poll = 0;
|
||||||
byte_without_poll = 0;
|
byte_without_poll = 0;
|
||||||
if (poll_retx_timer != NULL) {
|
if (poll_retx_timer.is_valid()) {
|
||||||
poll_retx_timer->reset();
|
poll_retx_timer.run();
|
||||||
poll_retx_timer->run();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *ptr = payload;
|
uint8_t* ptr = payload;
|
||||||
rlc_am_write_data_pdu_header(&new_header, &ptr);
|
rlc_am_write_data_pdu_header(&new_header, &ptr);
|
||||||
memcpy(ptr, tx_window[retx.sn].buf->msg, tx_window[retx.sn].buf->N_bytes);
|
memcpy(ptr, tx_window[retx.sn].buf->msg, tx_window[retx.sn].buf->N_bytes);
|
||||||
|
|
||||||
|
@ -626,24 +613,23 @@ int rlc_am::rlc_am_tx::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a
|
||||||
new_header.dc = RLC_DC_FIELD_DATA_PDU;
|
new_header.dc = RLC_DC_FIELD_DATA_PDU;
|
||||||
new_header.rf = 1;
|
new_header.rf = 1;
|
||||||
new_header.fi = RLC_FI_FIELD_NOT_START_OR_END_ALIGNED;
|
new_header.fi = RLC_FI_FIELD_NOT_START_OR_END_ALIGNED;
|
||||||
new_header.sn = old_header.sn;
|
new_header.sn = old_header.sn;
|
||||||
new_header.lsf = 0;
|
new_header.lsf = 0;
|
||||||
new_header.so = retx.so_start;
|
new_header.so = retx.so_start;
|
||||||
new_header.N_li = 0;
|
new_header.N_li = 0;
|
||||||
new_header.p = 0;
|
new_header.p = 0;
|
||||||
if (poll_required()) {
|
if (poll_required()) {
|
||||||
log->debug("%s setting poll bit to request status\n", RB_NAME);
|
log->debug("%s setting poll bit to request status\n", RB_NAME);
|
||||||
new_header.p = 1;
|
new_header.p = 1;
|
||||||
poll_sn = vt_s;
|
poll_sn = vt_s;
|
||||||
pdu_without_poll = 0;
|
pdu_without_poll = 0;
|
||||||
byte_without_poll = 0;
|
byte_without_poll = 0;
|
||||||
if (poll_retx_timer != NULL) {
|
if (poll_retx_timer.is_valid()) {
|
||||||
poll_retx_timer->reset();
|
poll_retx_timer.run();
|
||||||
poll_retx_timer->run();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t head_len = 0;
|
uint32_t head_len = 0;
|
||||||
uint32_t pdu_space = 0;
|
uint32_t pdu_space = 0;
|
||||||
|
|
||||||
head_len = rlc_am_packed_length(&new_header);
|
head_len = rlc_am_packed_length(&new_header);
|
||||||
|
@ -894,9 +880,8 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
|
||||||
poll_sn = vt_s;
|
poll_sn = vt_s;
|
||||||
pdu_without_poll = 0;
|
pdu_without_poll = 0;
|
||||||
byte_without_poll = 0;
|
byte_without_poll = 0;
|
||||||
if (poll_retx_timer != NULL) {
|
if (poll_retx_timer.is_valid()) {
|
||||||
poll_retx_timer->reset();
|
poll_retx_timer.run();
|
||||||
poll_retx_timer->run();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,8 +917,8 @@ void rlc_am::rlc_am_tx::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes)
|
||||||
|
|
||||||
log->info("%s Rx Status PDU: %s\n", RB_NAME, rlc_am_status_pdu_to_string(&status).c_str());
|
log->info("%s Rx Status PDU: %s\n", RB_NAME, rlc_am_status_pdu_to_string(&status).c_str());
|
||||||
|
|
||||||
if (poll_retx_timer != NULL) {
|
if (poll_retx_timer.is_valid()) {
|
||||||
poll_retx_timer->stop();
|
poll_retx_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// flush retx queue to avoid unordered SNs, we expect the Rx to request lost PDUs again
|
// flush retx queue to avoid unordered SNs, we expect the Rx to request lost PDUs again
|
||||||
|
@ -1118,19 +1103,14 @@ bool rlc_am::rlc_am_tx::retx_queue_has_sn(uint32_t sn)
|
||||||
rlc_am::rlc_am_rx::rlc_am_rx(rlc_am* parent_) :
|
rlc_am::rlc_am_rx::rlc_am_rx(rlc_am* parent_) :
|
||||||
parent(parent_),
|
parent(parent_),
|
||||||
pool(byte_buffer_pool::get_instance()),
|
pool(byte_buffer_pool::get_instance()),
|
||||||
log(parent_->log)
|
log(parent_->log),
|
||||||
|
reordering_timer(parent_->timers->get_unique_timer())
|
||||||
{
|
{
|
||||||
reordering_timer_id = parent->timers->get_unique_id();
|
|
||||||
reordering_timer = parent->timers->get(reordering_timer_id);
|
|
||||||
|
|
||||||
pthread_mutex_init(&mutex, NULL);
|
pthread_mutex_init(&mutex, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
rlc_am::rlc_am_rx::~rlc_am_rx()
|
rlc_am::rlc_am_rx::~rlc_am_rx()
|
||||||
{
|
{
|
||||||
reordering_timer->stop();
|
|
||||||
parent->timers->release_id(reordering_timer_id);
|
|
||||||
|
|
||||||
pthread_mutex_destroy(&mutex);
|
pthread_mutex_destroy(&mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1140,14 +1120,14 @@ bool rlc_am::rlc_am_rx::configure(rlc_am_config_t cfg_)
|
||||||
cfg = cfg_;
|
cfg = cfg_;
|
||||||
|
|
||||||
// check timers
|
// check timers
|
||||||
if (reordering_timer == NULL) {
|
if (not reordering_timer.is_valid()) {
|
||||||
log->error("Configuring RLC AM TX: timers not configured\n");
|
log->error("Configuring RLC AM TX: timers not configured\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure timer
|
// configure timer
|
||||||
if (cfg.t_reordering > 0) {
|
if (cfg.t_reordering > 0) {
|
||||||
reordering_timer->set(this, static_cast<uint32_t>(cfg.t_reordering));
|
reordering_timer.set(static_cast<uint32_t>(cfg.t_reordering), [this](uint32_t tid) { timer_expired(tid); });
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1162,8 +1142,8 @@ void rlc_am::rlc_am_rx::stop()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
|
|
||||||
if (parent->timers != NULL && reordering_timer != NULL) {
|
if (parent->timers != nullptr && reordering_timer.is_valid()) {
|
||||||
reordering_timer->stop();
|
reordering_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
rx_sdu.reset();
|
rx_sdu.reset();
|
||||||
|
@ -1283,22 +1263,21 @@ void rlc_am::rlc_am_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rl
|
||||||
reassemble_rx_sdus();
|
reassemble_rx_sdus();
|
||||||
|
|
||||||
// Update reordering variables and timers (36.322 v10.0.0 Section 5.1.3.2.3)
|
// Update reordering variables and timers (36.322 v10.0.0 Section 5.1.3.2.3)
|
||||||
if (reordering_timer != NULL) {
|
if (reordering_timer.is_valid()) {
|
||||||
if (reordering_timer->is_running()) {
|
if (reordering_timer.is_running()) {
|
||||||
if(vr_x == vr_r || (!inside_rx_window(vr_x) && vr_x != vr_mr)) {
|
if (vr_x == vr_r || (!inside_rx_window(vr_x) && vr_x != vr_mr)) {
|
||||||
log->debug("Stopping reordering timer.\n");
|
log->debug("Stopping reordering timer.\n");
|
||||||
reordering_timer->stop();
|
reordering_timer.stop();
|
||||||
} else {
|
} else {
|
||||||
log->debug("Leave reordering timer running.\n");
|
log->debug("Leave reordering timer running.\n");
|
||||||
}
|
}
|
||||||
debug_state();
|
debug_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not reordering_timer->is_running()) {
|
if (not reordering_timer.is_running()) {
|
||||||
if(RX_MOD_BASE(vr_h) > RX_MOD_BASE(vr_r)) {
|
if (RX_MOD_BASE(vr_h) > RX_MOD_BASE(vr_r)) {
|
||||||
log->debug("Starting reordering timer.\n");
|
log->debug("Starting reordering timer.\n");
|
||||||
reordering_timer->reset();
|
reordering_timer.run();
|
||||||
reordering_timer->run();
|
|
||||||
vr_x = vr_h;
|
vr_x = vr_h;
|
||||||
} else {
|
} else {
|
||||||
log->debug("Leave reordering timer stopped.\n");
|
log->debug("Leave reordering timer stopped.\n");
|
||||||
|
@ -1578,16 +1557,16 @@ void rlc_am::rlc_am_rx::write_pdu(uint8_t* payload, const uint32_t nof_bytes)
|
||||||
void rlc_am::rlc_am_rx::timer_expired(uint32_t timeout_id)
|
void rlc_am::rlc_am_rx::timer_expired(uint32_t timeout_id)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
if (reordering_timer != NULL && reordering_timer_id == timeout_id) {
|
if (reordering_timer.is_valid() and reordering_timer.id() == timeout_id) {
|
||||||
reordering_timer->reset();
|
// reordering_timer.run(); // FIXME: It was reset() before
|
||||||
log->debug("%s reordering timeout expiry - updating vr_ms (was %d)\n", RB_NAME, vr_ms);
|
log->debug("%s reordering timeout expiry - updating vr_ms (was %d)\n", RB_NAME, vr_ms);
|
||||||
|
|
||||||
// 36.322 v10 Section 5.1.3.2.4
|
// 36.322 v10 Section 5.1.3.2.4
|
||||||
vr_ms = vr_x;
|
vr_ms = vr_x;
|
||||||
std::map<uint32_t, rlc_amd_rx_pdu_t>::iterator it = rx_window.find(vr_ms);
|
std::map<uint32_t, rlc_amd_rx_pdu_t>::iterator it = rx_window.find(vr_ms);
|
||||||
while (rx_window.end() != it) {
|
while (rx_window.end() != it) {
|
||||||
vr_ms = (vr_ms + 1) % MOD;
|
vr_ms = (vr_ms + 1) % MOD;
|
||||||
it = rx_window.find(vr_ms);
|
it = rx_window.find(vr_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (poll_received) {
|
if (poll_received) {
|
||||||
|
@ -1595,8 +1574,7 @@ void rlc_am::rlc_am_rx::timer_expired(uint32_t timeout_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RX_MOD_BASE(vr_h) > RX_MOD_BASE(vr_ms)) {
|
if (RX_MOD_BASE(vr_h) > RX_MOD_BASE(vr_ms)) {
|
||||||
reordering_timer->reset();
|
reordering_timer.run();
|
||||||
reordering_timer->run();
|
|
||||||
vr_x = vr_h;
|
vr_x = vr_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ rlc_tm::rlc_tm(srslte::log* log_,
|
||||||
uint32_t lcid_,
|
uint32_t lcid_,
|
||||||
srsue::pdcp_interface_rlc* pdcp_,
|
srsue::pdcp_interface_rlc* pdcp_,
|
||||||
srsue::rrc_interface_rlc* rrc_,
|
srsue::rrc_interface_rlc* rrc_,
|
||||||
srslte::timers* timers_,
|
srslte::timer_handler* timers_,
|
||||||
uint32_t queue_len_) :
|
uint32_t queue_len_) :
|
||||||
ul_queue(queue_len_),
|
ul_queue(queue_len_),
|
||||||
log(log_),
|
log(log_),
|
||||||
|
|
|
@ -32,7 +32,7 @@ rlc_um::rlc_um(srslte::log* log_,
|
||||||
uint32_t lcid_,
|
uint32_t lcid_,
|
||||||
srsue::pdcp_interface_rlc* pdcp_,
|
srsue::pdcp_interface_rlc* pdcp_,
|
||||||
srsue::rrc_interface_rlc* rrc_,
|
srsue::rrc_interface_rlc* rrc_,
|
||||||
srslte::timers* timers_) :
|
srslte::timer_handler* timers_) :
|
||||||
lcid(lcid_),
|
lcid(lcid_),
|
||||||
pool(byte_buffer_pool::get_instance()),
|
pool(byte_buffer_pool::get_instance()),
|
||||||
rrc(rrc_),
|
rrc(rrc_),
|
||||||
|
@ -96,8 +96,8 @@ bool rlc_um::rlc_um_rx::configure(rlc_config_t cnfg_, std::string rb_name_)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set reordering timer
|
// set reordering timer
|
||||||
if (reordering_timer != NULL) {
|
if (reordering_timer.is_valid()) {
|
||||||
reordering_timer->set(this, cfg.um.t_reordering);
|
reordering_timer.set(cfg.um.t_reordering, [this](uint32_t tid) { timer_expired(tid); });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (cfg.um_nr.mod == 0) {
|
if (cfg.um_nr.mod == 0) {
|
||||||
|
@ -609,31 +609,26 @@ rlc_um::rlc_um_rx::rlc_um_rx(srslte::log* log_,
|
||||||
uint32_t lcid_,
|
uint32_t lcid_,
|
||||||
srsue::pdcp_interface_rlc* pdcp_,
|
srsue::pdcp_interface_rlc* pdcp_,
|
||||||
srsue::rrc_interface_rlc* rrc_,
|
srsue::rrc_interface_rlc* rrc_,
|
||||||
srslte::timers* timers_) :
|
srslte::timer_handler* timers_) :
|
||||||
pool(byte_buffer_pool::get_instance()),
|
pool(byte_buffer_pool::get_instance()),
|
||||||
log(log_),
|
log(log_),
|
||||||
pdcp(pdcp_),
|
pdcp(pdcp_),
|
||||||
rrc(rrc_),
|
rrc(rrc_),
|
||||||
timers(timers_),
|
timers(timers_),
|
||||||
lcid(lcid_)
|
lcid(lcid_),
|
||||||
|
reordering_timer(timers_->get_unique_timer())
|
||||||
{
|
{
|
||||||
reordering_timer_id = timers->get_unique_id();
|
|
||||||
reordering_timer = timers->get(reordering_timer_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rlc_um::rlc_um_rx::~rlc_um_rx()
|
rlc_um::rlc_um_rx::~rlc_um_rx() {}
|
||||||
{
|
|
||||||
reordering_timer->stop();
|
|
||||||
timers->release_id(reordering_timer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rlc_um::rlc_um_rx::reestablish()
|
void rlc_um::rlc_um_rx::reestablish()
|
||||||
{
|
{
|
||||||
// try to reassemble any SDUs if possible
|
// try to reassemble any SDUs if possible
|
||||||
if (reordering_timer != NULL) {
|
if (reordering_timer.is_valid()) {
|
||||||
if (reordering_timer->is_running()) {
|
if (reordering_timer.is_running()) {
|
||||||
reordering_timer->stop();
|
reordering_timer.stop();
|
||||||
timer_expired(reordering_timer_id);
|
timer_expired(reordering_timer.id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,12 +637,12 @@ void rlc_um::rlc_um_rx::reestablish()
|
||||||
rx_enabled = true;
|
rx_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rlc_um::rlc_um_rx::stop()
|
void rlc_um::rlc_um_rx::stop()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
reset();
|
reset();
|
||||||
reordering_timer->stop();
|
|
||||||
|
reordering_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rlc_um::rlc_um_rx::reset()
|
void rlc_um::rlc_um_rx::reset()
|
||||||
|
@ -723,17 +718,14 @@ void rlc_um::rlc_um_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
|
||||||
log->debug("Finished reassemble from received PDU\n");
|
log->debug("Finished reassemble from received PDU\n");
|
||||||
|
|
||||||
// Update reordering variables and timers
|
// Update reordering variables and timers
|
||||||
if(reordering_timer->is_running()) {
|
if (reordering_timer.is_running()) {
|
||||||
if(RX_MOD_BASE(vr_ux) <= RX_MOD_BASE(vr_ur) ||
|
if (RX_MOD_BASE(vr_ux) <= RX_MOD_BASE(vr_ur) || (!inside_reordering_window(vr_ux) && vr_ux != vr_uh)) {
|
||||||
(!inside_reordering_window(vr_ux) && vr_ux != vr_uh))
|
reordering_timer.stop();
|
||||||
{
|
|
||||||
reordering_timer->stop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!reordering_timer->is_running()) {
|
if (!reordering_timer.is_running()) {
|
||||||
if(RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) {
|
if (RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) {
|
||||||
reordering_timer->reset();
|
reordering_timer.run();
|
||||||
reordering_timer->run();
|
|
||||||
vr_ux = vr_uh;
|
vr_ux = vr_uh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1023,10 +1015,9 @@ void rlc_um::rlc_um_rx::reset_metrics()
|
||||||
void rlc_um::rlc_um_rx::timer_expired(uint32_t timeout_id)
|
void rlc_um::rlc_um_rx::timer_expired(uint32_t timeout_id)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
if (reordering_timer != NULL && reordering_timer_id == timeout_id) {
|
if (reordering_timer.is_valid() && reordering_timer.id() == timeout_id) {
|
||||||
// 36.322 v10 Section 5.1.2.2.4
|
// 36.322 v10 Section 5.1.2.2.4
|
||||||
log->info("%s reordering timeout expiry - updating vr_ur and reassembling\n",
|
log->info("%s reordering timeout expiry - updating vr_ur and reassembling\n", get_rb_name());
|
||||||
get_rb_name());
|
|
||||||
|
|
||||||
log->warning("Lost PDU SN: %d\n", vr_ur);
|
log->warning("Lost PDU SN: %d\n", vr_ur);
|
||||||
|
|
||||||
|
@ -1043,8 +1034,7 @@ void rlc_um::rlc_um_rx::timer_expired(uint32_t timeout_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) {
|
if (RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) {
|
||||||
reordering_timer->reset();
|
reordering_timer.run();
|
||||||
reordering_timer->run();
|
|
||||||
vr_ux = vr_uh;
|
vr_ux = vr_uh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,3 +75,6 @@ add_test(stack_procedure_test stack_procedure_test)
|
||||||
add_executable(queue_test queue_test.cc)
|
add_executable(queue_test queue_test.cc)
|
||||||
target_link_libraries(queue_test srslte_common ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(queue_test srslte_common ${CMAKE_THREAD_LIBS_INIT})
|
||||||
add_test(queue_test queue_test)
|
add_test(queue_test queue_test)
|
||||||
|
|
||||||
|
add_executable(timer_test timer_test.cc)
|
||||||
|
target_link_libraries(timer_test srslte_common)
|
||||||
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
/*
|
||||||
|
* 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/timers.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define TESTASSERT(cond) \
|
||||||
|
do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
std::cout << "[" << __FUNCTION__ << "][Line " << __LINE__ << "]: FAIL at " << (#cond) << std::endl; \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
using namespace srslte;
|
||||||
|
|
||||||
|
int timers2_test()
|
||||||
|
{
|
||||||
|
timer_handler timers;
|
||||||
|
uint32_t dur = 5;
|
||||||
|
|
||||||
|
{
|
||||||
|
timer_handler::unique_timer t = timers.get_unique_timer();
|
||||||
|
TESTASSERT(not t.is_running() and not t.is_expired());
|
||||||
|
TESTASSERT(t.id() == 0);
|
||||||
|
timer_handler::unique_timer t2 = timers.get_unique_timer();
|
||||||
|
TESTASSERT(not t2.is_running() and not t2.is_expired());
|
||||||
|
TESTASSERT(t2.id() == 1);
|
||||||
|
TESTASSERT(timers.nof_timers() == 2);
|
||||||
|
|
||||||
|
// TEST: Run multiple times with the same duration
|
||||||
|
bool callback_called = false;
|
||||||
|
t.set(dur, [&callback_called](int) { callback_called = true; });
|
||||||
|
TESTASSERT(timers.get_cur_time() == 0);
|
||||||
|
for (uint32_t runs = 0; runs < 3; ++runs) {
|
||||||
|
callback_called = false;
|
||||||
|
TESTASSERT(not t.is_running());
|
||||||
|
t.run();
|
||||||
|
TESTASSERT(t.is_running() and not t.is_expired());
|
||||||
|
for (uint32_t i = 0; i < dur - 1; ++i) {
|
||||||
|
timers.step_all();
|
||||||
|
TESTASSERT(t.is_running() and not t.is_expired());
|
||||||
|
}
|
||||||
|
timers.step_all();
|
||||||
|
TESTASSERT(not t.is_running() and t.is_expired());
|
||||||
|
TESTASSERT(callback_called);
|
||||||
|
}
|
||||||
|
TESTASSERT(timers.get_cur_time() == 3 * dur);
|
||||||
|
|
||||||
|
// TEST: interrupt a timer. check if callback was called
|
||||||
|
callback_called = false;
|
||||||
|
t.run();
|
||||||
|
timers.step_all();
|
||||||
|
TESTASSERT(t.is_running());
|
||||||
|
t.stop();
|
||||||
|
TESTASSERT(not t.is_running());
|
||||||
|
for (uint32_t i = 0; i < dur; ++i) {
|
||||||
|
timers.step_all();
|
||||||
|
TESTASSERT(not t.is_running());
|
||||||
|
}
|
||||||
|
TESTASSERT(not callback_called);
|
||||||
|
|
||||||
|
// TEST: call timer::run() when it is already running. Check if duration gets extended.
|
||||||
|
callback_called = false;
|
||||||
|
t.run();
|
||||||
|
timers.step_all();
|
||||||
|
TESTASSERT(t.is_running());
|
||||||
|
t.run(); // re-run
|
||||||
|
for (uint32_t i = 0; i < dur - 1; ++i) {
|
||||||
|
timers.step_all();
|
||||||
|
TESTASSERT(t.is_running());
|
||||||
|
}
|
||||||
|
timers.step_all();
|
||||||
|
TESTASSERT(not t.is_running());
|
||||||
|
TESTASSERT(callback_called);
|
||||||
|
|
||||||
|
// TEST: ordering of timers is respected
|
||||||
|
timer_handler::unique_timer t3 = timers.get_unique_timer();
|
||||||
|
TESTASSERT(t3.id() == 2);
|
||||||
|
int first_id = -1, last_id = -1;
|
||||||
|
auto callback = [&first_id, &last_id](int id) {
|
||||||
|
if (first_id < 0) {
|
||||||
|
printf("First timer id=%d\n", id);
|
||||||
|
first_id = id;
|
||||||
|
}
|
||||||
|
last_id = id;
|
||||||
|
};
|
||||||
|
t.set(4, callback);
|
||||||
|
t2.set(2, callback);
|
||||||
|
t3.set(6, callback);
|
||||||
|
t.run();
|
||||||
|
t2.run();
|
||||||
|
t3.run();
|
||||||
|
for (uint32_t i = 0; i < 5; ++i) {
|
||||||
|
timers.step_all();
|
||||||
|
TESTASSERT(i >= 3 or t.is_running());
|
||||||
|
TESTASSERT(i >= 1 or t2.is_running());
|
||||||
|
TESTASSERT(t3.is_running());
|
||||||
|
}
|
||||||
|
timers.step_all();
|
||||||
|
TESTASSERT(t.is_expired() and t2.is_expired() and t3.is_expired());
|
||||||
|
TESTASSERT(first_id == 1);
|
||||||
|
printf("Last timer id=%d\n", last_id);
|
||||||
|
TESTASSERT(last_id == 2);
|
||||||
|
}
|
||||||
|
// TEST: timer dtor is called and removes "timer" from "timers"
|
||||||
|
TESTASSERT(timers.nof_timers() == 0);
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int timers2_test2()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Description:
|
||||||
|
* - calling stop() early, forbids the timer from getting expired
|
||||||
|
* - calling stop() after timer has expired should be a noop
|
||||||
|
*/
|
||||||
|
timer_handler timers;
|
||||||
|
uint32_t duration = 2;
|
||||||
|
|
||||||
|
auto utimer = timers.get_unique_timer();
|
||||||
|
auto utimer2 = timers.get_unique_timer();
|
||||||
|
utimer.set(duration);
|
||||||
|
utimer2.set(duration);
|
||||||
|
|
||||||
|
// TEST 1: call utimer.stop() early and check if timer expires
|
||||||
|
utimer.run();
|
||||||
|
utimer2.run();
|
||||||
|
TESTASSERT(utimer.is_running() and not utimer.is_expired());
|
||||||
|
utimer.stop();
|
||||||
|
TESTASSERT(not utimer.is_running() and not utimer.is_expired());
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < 5; ++i) {
|
||||||
|
timers.step_all();
|
||||||
|
}
|
||||||
|
TESTASSERT(not utimer.is_expired());
|
||||||
|
TESTASSERT(utimer2.is_expired());
|
||||||
|
|
||||||
|
// TEST 2: call utimer.stop() after it expires and assert it is still expired
|
||||||
|
utimer2.stop();
|
||||||
|
TESTASSERT(utimer2.is_expired());
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int timers2_test3()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Description:
|
||||||
|
* - setting a new duration while the timer is already running should not stop timer, and should extend timeout
|
||||||
|
*/
|
||||||
|
timer_handler timers;
|
||||||
|
uint32_t duration = 5;
|
||||||
|
|
||||||
|
auto utimer = timers.get_unique_timer();
|
||||||
|
utimer.set(duration);
|
||||||
|
utimer.run();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < 2 * duration + 1; ++i) {
|
||||||
|
timers.step_all();
|
||||||
|
if ((i % 2) == 0) {
|
||||||
|
// extends lifetime
|
||||||
|
utimer.set(duration);
|
||||||
|
}
|
||||||
|
TESTASSERT(utimer.is_running());
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < duration - 1; ++i) {
|
||||||
|
timers.step_all();
|
||||||
|
TESTASSERT(utimer.is_running());
|
||||||
|
}
|
||||||
|
timers.step_all();
|
||||||
|
TESTASSERT(not utimer.is_running());
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
TESTASSERT(timers2_test() == SRSLTE_SUCCESS);
|
||||||
|
TESTASSERT(timers2_test2() == SRSLTE_SUCCESS);
|
||||||
|
TESTASSERT(timers2_test3() == SRSLTE_SUCCESS);
|
||||||
|
|
||||||
|
printf("Success\n");
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -140,7 +140,7 @@ bool basic_test()
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
|
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
timers timers(8);
|
timer_handler timers(8);
|
||||||
byte_buffer_t pdu_bufs[NBUFS];
|
byte_buffer_t pdu_bufs[NBUFS];
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
|
@ -199,8 +199,8 @@ bool concat_test()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
||||||
|
@ -264,9 +264,9 @@ bool segment_test(bool in_seq_rx)
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
||||||
|
@ -359,7 +359,7 @@ bool retx_test()
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
timers timers(8);
|
timer_handler timers(8);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
|
@ -453,7 +453,7 @@ bool resegment_test_1()
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
timers timers(8);
|
timer_handler timers(8);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
|
@ -559,7 +559,7 @@ bool resegment_test_2()
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
timers timers(8);
|
timer_handler timers(8);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
|
@ -661,8 +661,8 @@ bool resegment_test_3()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
||||||
|
@ -758,8 +758,8 @@ bool resegment_test_4()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
||||||
|
@ -857,8 +857,8 @@ bool resegment_test_5()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
||||||
|
@ -956,9 +956,9 @@ bool resegment_test_6()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
||||||
|
@ -1090,11 +1090,11 @@ bool resegment_test_7()
|
||||||
#if HAVE_PCAP
|
#if HAVE_PCAP
|
||||||
rlc_pcap pcap;
|
rlc_pcap pcap;
|
||||||
pcap.open("rlc_am_test7.pcap", 0);
|
pcap.open("rlc_am_test7.pcap", 0);
|
||||||
rlc_am_tester tester(&pcap);
|
rlc_am_tester tester(&pcap);
|
||||||
#else
|
#else
|
||||||
rlc_am_tester tester(NULL);
|
rlc_am_tester tester(NULL);
|
||||||
#endif
|
#endif
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
||||||
|
@ -1263,11 +1263,11 @@ bool resegment_test_8()
|
||||||
#if HAVE_PCAP
|
#if HAVE_PCAP
|
||||||
rlc_pcap pcap;
|
rlc_pcap pcap;
|
||||||
pcap.open("rlc_am_test8.pcap", 0);
|
pcap.open("rlc_am_test8.pcap", 0);
|
||||||
rlc_am_tester tester(&pcap);
|
rlc_am_tester tester(&pcap);
|
||||||
#else
|
#else
|
||||||
rlc_am_tester tester(NULL);
|
rlc_am_tester tester(NULL);
|
||||||
#endif
|
#endif
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
||||||
|
@ -1410,9 +1410,9 @@ bool reset_test()
|
||||||
srslte::log_filter log1("RLC_AM_1");
|
srslte::log_filter log1("RLC_AM_1");
|
||||||
log1.set_level(srslte::LOG_LEVEL_DEBUG);
|
log1.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
|
|
||||||
|
@ -1455,9 +1455,9 @@ bool resume_test()
|
||||||
srslte::log_filter log1("RLC_AM_1");
|
srslte::log_filter log1("RLC_AM_1");
|
||||||
log1.set_level(srslte::LOG_LEVEL_DEBUG);
|
log1.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
|
|
||||||
|
@ -1500,8 +1500,8 @@ bool stop_test()
|
||||||
srslte::log_filter log1("RLC_AM_1");
|
srslte::log_filter log1("RLC_AM_1");
|
||||||
log1.set_level(srslte::LOG_LEVEL_DEBUG);
|
log1.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
|
|
||||||
|
@ -1532,9 +1532,9 @@ bool status_pdu_test()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_am_tester tester;
|
rlc_am_tester tester;
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
rlc_am rlc1(&log1, 1, &tester, &tester, &timers);
|
||||||
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
rlc_am rlc2(&log2, 1, &tester, &tester, &timers);
|
||||||
|
|
|
@ -79,8 +79,8 @@ int basic_test()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_tester tester;
|
rlc_tester tester;
|
||||||
srslte::timers timers(1);
|
srslte::timer_handler timers(1);
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ public:
|
||||||
rlc_interface_mac* rlc2_,
|
rlc_interface_mac* rlc2_,
|
||||||
stress_test_args_t args_,
|
stress_test_args_t args_,
|
||||||
uint32_t lcid_,
|
uint32_t lcid_,
|
||||||
timers* timers_,
|
timer_handler* timers_,
|
||||||
rlc_pcap* pcap_ = NULL) :
|
rlc_pcap* pcap_ = NULL) :
|
||||||
run_enable(true),
|
run_enable(true),
|
||||||
rlc1(rlc1_),
|
rlc1(rlc1_),
|
||||||
|
@ -196,25 +196,21 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rlc_interface_mac *rlc1;
|
rlc_interface_mac* rlc1;
|
||||||
rlc_interface_mac *rlc2;
|
rlc_interface_mac* rlc2;
|
||||||
|
|
||||||
bool run_enable;
|
bool run_enable;
|
||||||
stress_test_args_t args;
|
stress_test_args_t args;
|
||||||
rlc_pcap* pcap;
|
rlc_pcap* pcap;
|
||||||
uint32_t lcid;
|
uint32_t lcid;
|
||||||
srslte::log_filter log;
|
srslte::log_filter log;
|
||||||
srslte::timers* timers = nullptr;
|
srslte::timer_handler* timers = nullptr;
|
||||||
|
|
||||||
std::mt19937 mt19937;
|
std::mt19937 mt19937;
|
||||||
std::uniform_real_distribution<float> real_dist;
|
std::uniform_real_distribution<float> real_dist;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class rlc_tester : public pdcp_interface_rlc, public rrc_interface_rlc, public thread
|
||||||
class rlc_tester
|
|
||||||
:public pdcp_interface_rlc
|
|
||||||
,public rrc_interface_rlc
|
|
||||||
,public thread
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
rlc_tester(rlc_interface_pdcp* rlc_, std::string name_, stress_test_args_t args_, uint32_t lcid_) :
|
rlc_tester(rlc_interface_pdcp* rlc_, std::string name_, stress_test_args_t args_, uint32_t lcid_) :
|
||||||
|
@ -339,7 +335,7 @@ void stress_test(stress_test_args_t args)
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
srslte::timers timers(8);
|
srslte::timer_handler timers(8);
|
||||||
|
|
||||||
rlc rlc1(&log1);
|
rlc rlc1(&log1);
|
||||||
rlc rlc2(&log2);
|
rlc rlc2(&log2);
|
||||||
|
|
|
@ -85,10 +85,10 @@ int rlc_um_nr_test1()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_um_tester tester;
|
rlc_um_tester tester;
|
||||||
srslte::timers timers(16);
|
srslte::timer_handler timers(16);
|
||||||
const uint32_t num_sdus = 5;
|
const uint32_t num_sdus = 5;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
||||||
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
||||||
|
@ -139,11 +139,11 @@ int rlc_um_nr_test2()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_um_tester tester;
|
rlc_um_tester tester;
|
||||||
srslte::timers timers(16);
|
srslte::timer_handler timers(16);
|
||||||
const uint32_t num_sdus = 1;
|
const uint32_t num_sdus = 1;
|
||||||
const uint32_t sdu_size = 100;
|
const uint32_t sdu_size = 100;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
||||||
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
||||||
|
|
|
@ -47,9 +47,9 @@ int basic_test()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_um_tester tester;
|
rlc_um_tester tester;
|
||||||
srslte::timers timers(16);
|
srslte::timer_handler timers(16);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
||||||
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
||||||
|
@ -116,9 +116,9 @@ int loss_test()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_um_tester tester;
|
rlc_um_tester tester;
|
||||||
srslte::timers timers(16);
|
srslte::timer_handler timers(16);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
||||||
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
||||||
|
@ -161,8 +161,11 @@ int loss_test()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step the reordering timer until expiry
|
// Step the reordering timer until expiry
|
||||||
while (!timers.get(1)->is_expired())
|
// while (!timers.get(1)->is_expired())
|
||||||
timers.get(1)->step();
|
// timers.get(1)->step();
|
||||||
|
while (timers.nof_running_timers() != 0) {
|
||||||
|
timers.step_all();
|
||||||
|
}
|
||||||
|
|
||||||
TESTASSERT(NBUFS - 1 == tester.sdus.size());
|
TESTASSERT(NBUFS - 1 == tester.sdus.size());
|
||||||
|
|
||||||
|
@ -177,9 +180,9 @@ int basic_mbsfn_test()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_um_tester tester;
|
rlc_um_tester tester;
|
||||||
srslte::timers timers(16);
|
srslte::timer_handler timers(16);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
||||||
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
||||||
|
@ -248,9 +251,9 @@ int reassmble_test()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_um_tester tester;
|
rlc_um_tester tester;
|
||||||
srslte::timers timers(16);
|
srslte::timer_handler timers(16);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
||||||
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
||||||
|
@ -357,9 +360,9 @@ int reassmble_test2()
|
||||||
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
log2.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
log1.set_hex_limit(-1);
|
log1.set_hex_limit(-1);
|
||||||
log2.set_hex_limit(-1);
|
log2.set_hex_limit(-1);
|
||||||
rlc_um_tester tester;
|
rlc_um_tester tester;
|
||||||
srslte::timers timers(16);
|
srslte::timer_handler timers(16);
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
rlc_um rlc1(&log1, 3, &tester, &tester, &timers);
|
||||||
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
rlc_um rlc2(&log2, 3, &tester, &tester, &timers);
|
||||||
|
|
|
@ -105,8 +105,8 @@ private:
|
||||||
srsenb::gtpu gtpu;
|
srsenb::gtpu gtpu;
|
||||||
srsenb::s1ap s1ap;
|
srsenb::s1ap s1ap;
|
||||||
|
|
||||||
srslte::logger* logger = nullptr;
|
srslte::logger* logger = nullptr;
|
||||||
srslte::timers timers;
|
srslte::timer_handler timers;
|
||||||
|
|
||||||
// Radio and PHY log are in enb.cc
|
// Radio and PHY log are in enb.cc
|
||||||
srslte::log_filter mac_log;
|
srslte::log_filter mac_log;
|
||||||
|
|
|
@ -44,11 +44,7 @@ public:
|
||||||
virtual bool process_pdus() = 0;
|
virtual bool process_pdus() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class mac : public mac_interface_phy_lte,
|
class mac : public mac_interface_phy_lte, public mac_interface_rlc, public mac_interface_rrc, public pdu_process_handler
|
||||||
public mac_interface_rlc,
|
|
||||||
public mac_interface_rrc,
|
|
||||||
public srslte::mac_interface_timers,
|
|
||||||
public pdu_process_handler
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mac();
|
mac();
|
||||||
|
@ -107,13 +103,8 @@ public:
|
||||||
|
|
||||||
bool process_pdus();
|
bool process_pdus();
|
||||||
|
|
||||||
// Interface for upper-layer timers
|
|
||||||
srslte::timers::timer* timer_get(uint32_t timer_id);
|
|
||||||
void timer_release_id(uint32_t timer_id);
|
|
||||||
u_int32_t timer_get_unique_id();
|
|
||||||
|
|
||||||
uint32_t get_current_tti();
|
uint32_t get_current_tti();
|
||||||
void get_metrics(mac_metrics_t metrics[ENB_METRICS_MAX_USERS]);
|
void get_metrics(mac_metrics_t metrics[ENB_METRICS_MAX_USERS]);
|
||||||
void write_mcch(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13, asn1::rrc::mcch_msg_s* mcch);
|
void write_mcch(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13, asn1::rrc::mcch_msg_s* mcch);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -176,30 +167,31 @@ private:
|
||||||
asn1::rrc::sib_type13_r9_s sib13;
|
asn1::rrc::sib_type13_r9_s sib13;
|
||||||
|
|
||||||
const static int mtch_payload_len = 10000;
|
const static int mtch_payload_len = 10000;
|
||||||
uint8_t mtch_payload_buffer[mtch_payload_len];
|
uint8_t mtch_payload_buffer[mtch_payload_len];
|
||||||
|
|
||||||
/* Functions for MAC Timers */
|
/* Functions for MAC Timers */
|
||||||
srslte::timers timers_db;
|
srslte::timer_handler timers_db;
|
||||||
void setup_timers();
|
void setup_timers();
|
||||||
|
|
||||||
// pointer to MAC PCAP object
|
// pointer to MAC PCAP object
|
||||||
srslte::mac_pcap* pcap;
|
srslte::mac_pcap* pcap;
|
||||||
|
|
||||||
|
|
||||||
/* Class to run upper-layer timers with normal priority */
|
/* Class to run upper-layer timers with normal priority */
|
||||||
class timer_thread : public thread {
|
class timer_thread : public thread
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
timer_thread(mac* parent_, srslte::timers* t) : ttisync(10240), timers(t), running(false), parent(parent_), thread("MAC_TIMER") { start(); }
|
timer_thread(mac* parent_, srslte::timer_handler* t) : ttisync(10240), timers(t), running(false), parent(parent_), thread("MAC_TIMER") { start(); }
|
||||||
void tti_clock();
|
void tti_clock();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void run_thread();
|
void run_thread();
|
||||||
srslte::tti_sync_cv ttisync;
|
srslte::tti_sync_cv ttisync;
|
||||||
srslte::timers *timers;
|
srslte::timer_handler *timers;
|
||||||
mac *parent;
|
mac *parent;
|
||||||
bool running;
|
bool running;
|
||||||
};
|
};
|
||||||
timer_thread timers_thread;
|
timer_thread timers_thread;
|
||||||
|
|
||||||
/* Class to process MAC PDUs from DEMUX unit */
|
/* Class to process MAC PDUs from DEMUX unit */
|
||||||
class pdu_process : public thread {
|
class pdu_process : public thread {
|
||||||
|
|
|
@ -31,21 +31,19 @@ typedef struct {
|
||||||
uint32_t lcid;
|
uint32_t lcid;
|
||||||
uint32_t plmn;
|
uint32_t plmn;
|
||||||
uint16_t mtch_stop;
|
uint16_t mtch_stop;
|
||||||
uint8_t *payload;
|
uint8_t* payload;
|
||||||
}mch_service_t;
|
} mch_service_t;
|
||||||
|
|
||||||
namespace srsenb {
|
namespace srsenb {
|
||||||
|
|
||||||
class rlc : public rlc_interface_mac,
|
class rlc : public rlc_interface_mac, public rlc_interface_rrc, public rlc_interface_pdcp
|
||||||
public rlc_interface_rrc,
|
|
||||||
public rlc_interface_pdcp
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void init(pdcp_interface_rlc* pdcp_,
|
void init(pdcp_interface_rlc* pdcp_,
|
||||||
rrc_interface_rlc* rrc_,
|
rrc_interface_rlc* rrc_,
|
||||||
mac_interface_rlc* mac_,
|
mac_interface_rlc* mac_,
|
||||||
srslte::timers* timers_,
|
srslte::timer_handler* timers_,
|
||||||
srslte::log* log_h);
|
srslte::log* log_h);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
// rlc_interface_rrc
|
// rlc_interface_rrc
|
||||||
|
@ -88,15 +86,15 @@ private:
|
||||||
|
|
||||||
pthread_rwlock_t rwlock;
|
pthread_rwlock_t rwlock;
|
||||||
|
|
||||||
std::map<uint32_t,user_interface> users;
|
std::map<uint32_t, user_interface> users;
|
||||||
std::vector<mch_service_t> mch_services;
|
std::vector<mch_service_t> mch_services;
|
||||||
|
|
||||||
mac_interface_rlc *mac;
|
mac_interface_rlc* mac;
|
||||||
pdcp_interface_rlc *pdcp;
|
pdcp_interface_rlc* pdcp;
|
||||||
rrc_interface_rlc* rrc;
|
rrc_interface_rlc* rrc;
|
||||||
srslte::log* log_h;
|
srslte::log* log_h;
|
||||||
srslte::byte_buffer_pool* pool;
|
srslte::byte_buffer_pool* pool;
|
||||||
srslte::timers* timers;
|
srslte::timer_handler* timers;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace srsenb
|
} // namespace srsenb
|
||||||
|
|
|
@ -841,28 +841,6 @@ void mac::tti_clock()
|
||||||
timers_thread.tti_clock();
|
timers_thread.tti_clock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
*
|
|
||||||
* Interface for upper layer timers
|
|
||||||
*
|
|
||||||
*******************************************************/
|
|
||||||
uint32_t mac::timer_get_unique_id()
|
|
||||||
{
|
|
||||||
return timers_db.get_unique_id();
|
|
||||||
}
|
|
||||||
|
|
||||||
void mac::timer_release_id(uint32_t timer_id)
|
|
||||||
{
|
|
||||||
timers_db.release_id(timer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Front-end to upper-layer timers */
|
|
||||||
srslte::timers::timer* mac::timer_get(uint32_t timer_id)
|
|
||||||
{
|
|
||||||
return timers_db.get(timer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
*
|
*
|
||||||
* Class to run timers with normal priority
|
* Class to run timers with normal priority
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
|
|
||||||
namespace srsenb {
|
namespace srsenb {
|
||||||
|
|
||||||
void rlc::init(pdcp_interface_rlc* pdcp_,
|
void rlc::init(pdcp_interface_rlc* pdcp_,
|
||||||
rrc_interface_rlc* rrc_,
|
rrc_interface_rlc* rrc_,
|
||||||
mac_interface_rlc* mac_,
|
mac_interface_rlc* mac_,
|
||||||
srslte::timers* timers_,
|
srslte::timer_handler* timers_,
|
||||||
srslte::log* log_h_)
|
srslte::log* log_h_)
|
||||||
{
|
{
|
||||||
pdcp = pdcp_;
|
pdcp = pdcp_;
|
||||||
rrc = rrc_;
|
rrc = rrc_;
|
||||||
|
|
|
@ -44,10 +44,10 @@ class demux : public srslte::pdu_queue::process_callback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
demux(srslte::log* log_);
|
demux(srslte::log* log_);
|
||||||
void init(phy_interface_mac_common* phy_h_,
|
void init(phy_interface_mac_common* phy_h_,
|
||||||
rlc_interface_mac* rlc,
|
rlc_interface_mac* rlc,
|
||||||
mac_interface_demux* mac,
|
mac_interface_demux* mac,
|
||||||
srslte::timers::timer* time_alignment_timer);
|
srslte::timer_handler::unique_timer* time_alignment_timer);
|
||||||
|
|
||||||
bool process_pdus();
|
bool process_pdus();
|
||||||
uint8_t* request_buffer(uint32_t len);
|
uint8_t* request_buffer(uint32_t len);
|
||||||
|
@ -77,15 +77,15 @@ private:
|
||||||
void process_sch_pdu(srslte::sch_pdu* pdu);
|
void process_sch_pdu(srslte::sch_pdu* pdu);
|
||||||
void process_mch_pdu(srslte::mch_pdu* pdu);
|
void process_mch_pdu(srslte::mch_pdu* pdu);
|
||||||
|
|
||||||
bool process_ce(srslte::sch_subh *subheader);
|
bool process_ce(srslte::sch_subh* subheader);
|
||||||
|
|
||||||
bool is_uecrid_successful;
|
bool is_uecrid_successful;
|
||||||
|
|
||||||
phy_interface_mac_common* phy_h = nullptr;
|
phy_interface_mac_common* phy_h = nullptr;
|
||||||
srslte::log* log_h = nullptr;
|
srslte::log* log_h = nullptr;
|
||||||
srslte::timers::timer* time_alignment_timer = nullptr;
|
srslte::timer_handler::unique_timer* time_alignment_timer = nullptr;
|
||||||
rlc_interface_mac* rlc = nullptr;
|
rlc_interface_mac* rlc = nullptr;
|
||||||
mac_interface_demux* mac = nullptr;
|
mac_interface_demux* mac = nullptr;
|
||||||
|
|
||||||
// Buffer of PDUs
|
// Buffer of PDUs
|
||||||
srslte::pdu_queue pdus;
|
srslte::pdu_queue pdus;
|
||||||
|
|
|
@ -40,10 +40,10 @@ class dl_harq_entity
|
||||||
public:
|
public:
|
||||||
dl_harq_entity();
|
dl_harq_entity();
|
||||||
|
|
||||||
bool init(srslte::log* log_h,
|
bool init(srslte::log* log_h,
|
||||||
mac_interface_rrc::ue_rnti_t* rntis,
|
mac_interface_rrc::ue_rnti_t* rntis,
|
||||||
srslte::timers::timer* timer_aligment_timer,
|
srslte::timer_handler::unique_timer* timer_aligment_timer,
|
||||||
demux* demux_unit);
|
demux* demux_unit);
|
||||||
void reset();
|
void reset();
|
||||||
void start_pcap(srslte::mac_pcap* pcap_);
|
void start_pcap(srslte::mac_pcap* pcap_);
|
||||||
|
|
||||||
|
@ -117,20 +117,20 @@ private:
|
||||||
|
|
||||||
uint32_t get_harq_sps_pid(uint32_t tti);
|
uint32_t get_harq_sps_pid(uint32_t tti);
|
||||||
|
|
||||||
dl_sps dl_sps_assig;
|
dl_sps dl_sps_assig;
|
||||||
|
|
||||||
std::vector<dl_harq_process> proc;
|
std::vector<dl_harq_process> proc;
|
||||||
dl_harq_process bcch_proc;
|
dl_harq_process bcch_proc;
|
||||||
srslte::timers::timer *timer_aligment_timer;
|
srslte::timer_handler::unique_timer* timer_aligment_timer = nullptr;
|
||||||
demux *demux_unit;
|
demux* demux_unit;
|
||||||
srslte::log *log_h;
|
srslte::log* log_h;
|
||||||
srslte::mac_pcap* pcap;
|
srslte::mac_pcap* pcap;
|
||||||
mac_interface_rrc::ue_rnti_t* rntis;
|
mac_interface_rrc::ue_rnti_t* rntis;
|
||||||
uint16_t last_temporal_crnti;
|
uint16_t last_temporal_crnti;
|
||||||
int si_window_start;
|
int si_window_start;
|
||||||
|
|
||||||
float average_retx;
|
float average_retx;
|
||||||
uint64_t nof_pkts;
|
uint64_t nof_pkts;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::unique_ptr<dl_harq_entity> dl_harq_entity_ptr;
|
typedef std::unique_ptr<dl_harq_entity> dl_harq_entity_ptr;
|
||||||
|
|
|
@ -45,7 +45,6 @@ namespace srsue {
|
||||||
class mac : public mac_interface_phy_lte,
|
class mac : public mac_interface_phy_lte,
|
||||||
public mac_interface_rrc,
|
public mac_interface_rrc,
|
||||||
public srslte::timer_callback,
|
public srslte::timer_callback,
|
||||||
public srslte::mac_interface_timers,
|
|
||||||
public mac_interface_demux
|
public mac_interface_demux
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -54,7 +53,7 @@ public:
|
||||||
bool init(phy_interface_mac_lte* phy,
|
bool init(phy_interface_mac_lte* phy,
|
||||||
rlc_interface_mac* rlc,
|
rlc_interface_mac* rlc,
|
||||||
rrc_interface_mac* rrc,
|
rrc_interface_mac* rrc,
|
||||||
srslte::timers* timers_,
|
srslte::timer_handler* timers_,
|
||||||
stack_interface_mac* stack);
|
stack_interface_mac* stack);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
@ -113,11 +112,6 @@ public:
|
||||||
|
|
||||||
uint32_t get_current_tti();
|
uint32_t get_current_tti();
|
||||||
|
|
||||||
// Interface for upper-layer timers
|
|
||||||
srslte::timers::timer* timer_get(uint32_t timer_id);
|
|
||||||
void timer_release_id(uint32_t timer_id);
|
|
||||||
uint32_t timer_get_unique_id();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void clear_rntis();
|
void clear_rntis();
|
||||||
|
|
||||||
|
@ -169,10 +163,10 @@ private:
|
||||||
srslte::mch_pdu mch_msg;
|
srslte::mch_pdu mch_msg;
|
||||||
|
|
||||||
/* Functions for MAC Timers */
|
/* Functions for MAC Timers */
|
||||||
uint32_t timer_alignment = 0;
|
srslte::timer_handler::unique_timer timer_alignment;
|
||||||
void setup_timers(int time_alignment_timer);
|
void setup_timers(int time_alignment_timer);
|
||||||
void timer_alignment_expire();
|
void timer_alignment_expire();
|
||||||
srslte::timers* timers = nullptr;
|
srslte::timer_handler* timers = nullptr;
|
||||||
|
|
||||||
// pointer to MAC PCAP object
|
// pointer to MAC PCAP object
|
||||||
srslte::mac_pcap* pcap = nullptr;
|
srslte::mac_pcap* pcap = nullptr;
|
||||||
|
|
|
@ -55,7 +55,7 @@ class bsr_proc : public srslte::timer_callback, public bsr_interface_mux
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bsr_proc();
|
bsr_proc();
|
||||||
void init(rlc_interface_mac* rlc, srslte::log* log_h, srslte::timers* timers_db);
|
void init(rlc_interface_mac* rlc, srslte::log* log_h, srslte::timer_handler* timers_db);
|
||||||
void step(uint32_t tti);
|
void step(uint32_t tti);
|
||||||
void reset();
|
void reset();
|
||||||
void set_config(srslte::bsr_cfg_t& bsr_cfg);
|
void set_config(srslte::bsr_cfg_t& bsr_cfg);
|
||||||
|
@ -73,14 +73,14 @@ private:
|
||||||
|
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
|
||||||
bool reset_sr;
|
bool reset_sr;
|
||||||
srslte::timers *timers_db;
|
srslte::timer_handler* timers_db;
|
||||||
srslte::log *log_h;
|
srslte::log* log_h;
|
||||||
rlc_interface_mac *rlc;
|
rlc_interface_mac* rlc;
|
||||||
|
|
||||||
srslte::bsr_cfg_t bsr_cfg;
|
srslte::bsr_cfg_t bsr_cfg;
|
||||||
|
|
||||||
bool initiated;
|
bool initiated;
|
||||||
|
|
||||||
const static int NOF_LCG = 4;
|
const static int NOF_LCG = 4;
|
||||||
|
|
||||||
|
@ -109,11 +109,11 @@ private:
|
||||||
bool check_any_channel();
|
bool check_any_channel();
|
||||||
uint32_t get_buffer_state_lcg(uint32_t lcg);
|
uint32_t get_buffer_state_lcg(uint32_t lcg);
|
||||||
bool generate_bsr(bsr_t* bsr, uint32_t nof_padding_bytes);
|
bool generate_bsr(bsr_t* bsr, uint32_t nof_padding_bytes);
|
||||||
char* bsr_type_tostring(triggered_bsr_type_t type);
|
char* bsr_type_tostring(triggered_bsr_type_t type);
|
||||||
char* bsr_format_tostring(bsr_format_t format);
|
char* bsr_format_tostring(bsr_format_t format);
|
||||||
|
|
||||||
uint32_t timer_periodic_id;
|
srslte::timer_handler::unique_timer timer_periodic;
|
||||||
uint32_t timer_retx_id;
|
srslte::timer_handler::unique_timer timer_retx;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace srsue
|
} // namespace srsue
|
||||||
|
|
|
@ -37,32 +37,30 @@ class phr_proc : public srslte::timer_callback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
phr_proc();
|
phr_proc();
|
||||||
void init(phy_interface_mac_lte* phy_h, srslte::log* log_h_, srslte::timers* timers_db_);
|
void init(phy_interface_mac_lte* phy_h, srslte::log* log_h_, srslte::timer_handler* timers_db_);
|
||||||
void set_config(srslte::phr_cfg_t& cfg);
|
void set_config(srslte::phr_cfg_t& cfg);
|
||||||
void step(uint32_t tti);
|
void step(uint32_t tti);
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
bool generate_phr_on_ul_grant(float *phr);
|
bool generate_phr_on_ul_grant(float* phr);
|
||||||
bool is_extended();
|
bool is_extended();
|
||||||
void timer_expired(uint32_t timer_id);
|
void timer_expired(uint32_t timer_id);
|
||||||
|
|
||||||
void start_timer();
|
void start_timer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool pathloss_changed();
|
bool pathloss_changed();
|
||||||
|
|
||||||
srslte::log* log_h;
|
srslte::log* log_h;
|
||||||
phy_interface_mac_lte* phy_h;
|
phy_interface_mac_lte* phy_h;
|
||||||
srslte::timers* timers_db;
|
srslte::timer_handler* timers_db;
|
||||||
srslte::phr_cfg_t phr_cfg;
|
srslte::phr_cfg_t phr_cfg;
|
||||||
bool initiated;
|
bool initiated;
|
||||||
int last_pathloss_db;
|
int last_pathloss_db;
|
||||||
bool phr_is_triggered;
|
bool phr_is_triggered;
|
||||||
|
|
||||||
uint32_t timer_periodic_id;
|
|
||||||
uint32_t timer_prohibit_id;
|
|
||||||
|
|
||||||
|
srslte::timer_handler::unique_timer timer_periodic;
|
||||||
|
srslte::timer_handler::unique_timer timer_prohibit;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace srsue
|
} // namespace srsue
|
||||||
|
|
|
@ -59,24 +59,21 @@ public:
|
||||||
started_by_pdcch = false;
|
started_by_pdcch = false;
|
||||||
rar_grant_nbytes = 0;
|
rar_grant_nbytes = 0;
|
||||||
|
|
||||||
noncontention_enabled = false;
|
noncontention_enabled = false;
|
||||||
next_preamble_idx = 0;
|
next_preamble_idx = 0;
|
||||||
next_prach_mask = 0;
|
next_prach_mask = 0;
|
||||||
|
|
||||||
time_alignment_timer = NULL;
|
|
||||||
contention_resolution_timer = NULL;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
~ra_proc();
|
~ra_proc();
|
||||||
|
|
||||||
void init(phy_interface_mac_lte* phy_h,
|
void init(phy_interface_mac_lte* phy_h,
|
||||||
rrc_interface_mac* rrc_,
|
rrc_interface_mac* rrc_,
|
||||||
srslte::log* log_h,
|
srslte::log* log_h,
|
||||||
mac_interface_rrc::ue_rnti_t* rntis,
|
mac_interface_rrc::ue_rnti_t* rntis,
|
||||||
srslte::timers::timer* time_alignment_timer_,
|
srslte::timer_handler::unique_timer* time_alignment_timer_,
|
||||||
srslte::timers::timer* contention_resolution_timer_,
|
srslte::timer_handler::unique_timer contention_resolution_timer_,
|
||||||
mux* mux_unit,
|
mux* mux_unit,
|
||||||
stack_interface_mac* stack_);
|
stack_interface_mac* stack_);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
@ -171,17 +168,17 @@ private:
|
||||||
rrc_interface_mac* rrc;
|
rrc_interface_mac* rrc;
|
||||||
stack_interface_mac* stack;
|
stack_interface_mac* stack;
|
||||||
|
|
||||||
srslte::timers::timer* time_alignment_timer;
|
srslte::timer_handler::unique_timer* time_alignment_timer = nullptr;
|
||||||
srslte::timers::timer* contention_resolution_timer;
|
srslte::timer_handler::unique_timer contention_resolution_timer;
|
||||||
|
|
||||||
mac_interface_rrc::ue_rnti_t *rntis;
|
mac_interface_rrc::ue_rnti_t* rntis;
|
||||||
|
|
||||||
uint64_t transmitted_contention_id;
|
uint64_t transmitted_contention_id;
|
||||||
uint16_t transmitted_crnti;
|
uint16_t transmitted_crnti;
|
||||||
|
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
|
|
||||||
bool ra_is_ho;
|
bool ra_is_ho;
|
||||||
bool started_by_pdcch;
|
bool started_by_pdcch;
|
||||||
uint32_t rar_grant_nbytes;
|
uint32_t rar_grant_nbytes;
|
||||||
bool rar_received;
|
bool rar_received;
|
||||||
|
|
|
@ -303,7 +303,7 @@ public:
|
||||||
nas_interface_rrc* nas_,
|
nas_interface_rrc* nas_,
|
||||||
usim_interface_rrc* usim_,
|
usim_interface_rrc* usim_,
|
||||||
gw_interface_rrc* gw_,
|
gw_interface_rrc* gw_,
|
||||||
srslte::timers* timers_,
|
srslte::timer_handler* timers_,
|
||||||
stack_interface_rrc* stack_,
|
stack_interface_rrc* stack_,
|
||||||
const rrc_args_t& args_);
|
const rrc_args_t& args_);
|
||||||
|
|
||||||
|
@ -419,13 +419,13 @@ private:
|
||||||
std::map<uint32_t, asn1::rrc::drb_to_add_mod_s> drbs;
|
std::map<uint32_t, asn1::rrc::drb_to_add_mod_s> drbs;
|
||||||
|
|
||||||
// RRC constants and timers
|
// RRC constants and timers
|
||||||
srslte::timers* timers = nullptr;
|
srslte::timer_handler* timers = nullptr;
|
||||||
uint32_t n310_cnt = 0, N310 = 0;
|
uint32_t n310_cnt, N310 = 0;
|
||||||
uint32_t n311_cnt = 0, N311 = 0;
|
uint32_t n311_cnt, N311 = 0;
|
||||||
uint32_t t300 = 0, t301 = 0, t302 = 0, t310 = 0, t311 = 0, t304 = 0;
|
srslte::timer_handler::unique_timer t300, t301, t302, t310, t311, t304;
|
||||||
|
|
||||||
// Radio bearers
|
// Radio bearers
|
||||||
typedef enum{
|
typedef enum {
|
||||||
RB_ID_SRB0 = 0,
|
RB_ID_SRB0 = 0,
|
||||||
RB_ID_SRB1,
|
RB_ID_SRB1,
|
||||||
RB_ID_SRB2,
|
RB_ID_SRB2,
|
||||||
|
@ -530,12 +530,12 @@ private:
|
||||||
} meas_value_t;
|
} meas_value_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t nof_reports_sent;
|
uint32_t nof_reports_sent;
|
||||||
uint32_t report_id;
|
uint32_t report_id;
|
||||||
uint32_t object_id;
|
uint32_t object_id;
|
||||||
bool triggered;
|
bool triggered;
|
||||||
uint32_t periodic_timer;
|
srslte::timer_handler::unique_timer periodic_timer;
|
||||||
std::map<uint32_t, meas_value_t> cell_values; // Value for each PCI in this object
|
std::map<uint32_t, meas_value_t> cell_values; // Value for each PCI in this object
|
||||||
} meas_t;
|
} meas_t;
|
||||||
|
|
||||||
std::map<uint32_t, meas_obj_t> objects;
|
std::map<uint32_t, meas_obj_t> objects;
|
||||||
|
@ -545,7 +545,7 @@ private:
|
||||||
rrc* parent = nullptr;
|
rrc* parent = nullptr;
|
||||||
srslte::log* log_h = nullptr;
|
srslte::log* log_h = nullptr;
|
||||||
phy_interface_rrc_lte* phy = nullptr;
|
phy_interface_rrc_lte* phy = nullptr;
|
||||||
srslte::timers* timers = nullptr;
|
srslte::timer_handler* timers = nullptr;
|
||||||
|
|
||||||
uint32_t filter_k_rsrp, filter_k_rsrq = 0;
|
uint32_t filter_k_rsrp, filter_k_rsrq = 0;
|
||||||
float filter_a[NOF_MEASUREMENTS] = {};
|
float filter_a[NOF_MEASUREMENTS] = {};
|
||||||
|
|
|
@ -132,7 +132,7 @@ private:
|
||||||
srsue::stack_args_t args;
|
srsue::stack_args_t args;
|
||||||
|
|
||||||
// timers
|
// timers
|
||||||
srslte::timers timers;
|
srslte::timer_handler timers;
|
||||||
|
|
||||||
// UE stack logging
|
// UE stack logging
|
||||||
srslte::logger* logger = nullptr;
|
srslte::logger* logger = nullptr;
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace srsue {
|
||||||
class nas : public nas_interface_rrc, public nas_interface_ue, public srslte::timer_callback
|
class nas : public nas_interface_rrc, public nas_interface_ue, public srslte::timer_callback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nas(srslte::log* log_, srslte::timers* timers_);
|
nas(srslte::log* log_, srslte::timer_handler* timers_);
|
||||||
void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_, const nas_args_t& args_);
|
void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_, const nas_args_t& args_);
|
||||||
void stop();
|
void stop();
|
||||||
void run_tti(uint32_t tti) final;
|
void run_tti(uint32_t tti) final;
|
||||||
|
@ -131,9 +131,9 @@ private:
|
||||||
uint8_t transaction_id = 0;
|
uint8_t transaction_id = 0;
|
||||||
|
|
||||||
// timers
|
// timers
|
||||||
srslte::timers* timers = nullptr;
|
srslte::timer_handler* timers = nullptr;
|
||||||
uint32_t t3410 = 0; // started when attach request is sent, on expiry, start t3411
|
srslte::timer_handler::unique_timer t3410; // started when attach request is sent, on expiry, start t3411
|
||||||
uint32_t t3411 = 0; // started when attach failed
|
srslte::timer_handler::unique_timer t3411; // started when attach failed
|
||||||
|
|
||||||
const uint32_t t3410_duration_ms = 15 * 1000; // 15s according to TS 24.301 Sec 10.2
|
const uint32_t t3410_duration_ms = 15 * 1000; // 15s according to TS 24.301 Sec 10.2
|
||||||
const uint32_t t3411_duration_ms = 10 * 1000; // 10s according to TS 24.301 Sec 10.2
|
const uint32_t t3411_duration_ms = 10 * 1000; // 10s according to TS 24.301 Sec 10.2
|
||||||
|
|
|
@ -43,10 +43,10 @@ demux::demux(srslte::log* log_) :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void demux::init(phy_interface_mac_common* phy_,
|
void demux::init(phy_interface_mac_common* phy_,
|
||||||
rlc_interface_mac* rlc_,
|
rlc_interface_mac* rlc_,
|
||||||
mac_interface_demux* mac_,
|
mac_interface_demux* mac_,
|
||||||
srslte::timers::timer* time_alignment_timer_)
|
srslte::timer_handler::unique_timer* time_alignment_timer_)
|
||||||
{
|
{
|
||||||
phy_h = phy_;
|
phy_h = phy_;
|
||||||
rlc = rlc_;
|
rlc = rlc_;
|
||||||
|
@ -275,7 +275,6 @@ bool demux::process_ce(srslte::sch_subh *subh) {
|
||||||
Info("Received TA=%d\n", subh->get_ta_cmd());
|
Info("Received TA=%d\n", subh->get_ta_cmd());
|
||||||
// Start or restart timeAlignmentTimer only if running
|
// Start or restart timeAlignmentTimer only if running
|
||||||
if (time_alignment_timer->is_running()) {
|
if (time_alignment_timer->is_running()) {
|
||||||
time_alignment_timer->reset();
|
|
||||||
time_alignment_timer->run();
|
time_alignment_timer->run();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -44,15 +44,15 @@ dl_harq_entity::dl_harq_entity() : proc(SRSLTE_MAX_HARQ_PROC)
|
||||||
nof_pkts = 0;
|
nof_pkts = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dl_harq_entity::init(srslte::log* log_h,
|
bool dl_harq_entity::init(srslte::log* log_h,
|
||||||
mac_interface_rrc::ue_rnti_t* rntis,
|
mac_interface_rrc::ue_rnti_t* rntis,
|
||||||
srslte::timers::timer* timer_aligment_timer,
|
srslte::timer_handler::unique_timer* timer_aligment_timer_,
|
||||||
demux* demux_unit)
|
demux* demux_unit)
|
||||||
{
|
{
|
||||||
this->timer_aligment_timer = timer_aligment_timer;
|
timer_aligment_timer = timer_aligment_timer_;
|
||||||
this->demux_unit = demux_unit;
|
this->demux_unit = demux_unit;
|
||||||
this->log_h = log_h;
|
this->log_h = log_h;
|
||||||
this->rntis = rntis;
|
this->rntis = rntis;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < SRSLTE_MAX_HARQ_PROC; i++) {
|
for (uint32_t i = 0; i < SRSLTE_MAX_HARQ_PROC; i++) {
|
||||||
if (!proc[i].init(i, this)) {
|
if (!proc[i].init(i, this)) {
|
||||||
|
|
|
@ -68,7 +68,7 @@ mac::~mac()
|
||||||
bool mac::init(phy_interface_mac_lte* phy,
|
bool mac::init(phy_interface_mac_lte* phy,
|
||||||
rlc_interface_mac* rlc,
|
rlc_interface_mac* rlc,
|
||||||
rrc_interface_mac* rrc,
|
rrc_interface_mac* rrc,
|
||||||
srslte::timers* timers_,
|
srslte::timer_handler* timers_,
|
||||||
stack_interface_mac* stack_)
|
stack_interface_mac* stack_)
|
||||||
{
|
{
|
||||||
phy_h = phy;
|
phy_h = phy;
|
||||||
|
@ -77,26 +77,20 @@ bool mac::init(phy_interface_mac_lte* phy,
|
||||||
timers = timers_;
|
timers = timers_;
|
||||||
stack_h = stack_;
|
stack_h = stack_;
|
||||||
|
|
||||||
timer_alignment = timers->get_unique_id();
|
timer_alignment = timers->get_unique_timer();
|
||||||
uint32_t contention_resolution_timer = timers->get_unique_id();
|
srslte::timer_handler::unique_timer contention_resolution_timer = timers->get_unique_timer();
|
||||||
|
|
||||||
bsr_procedure.init(rlc_h, log_h, timers);
|
bsr_procedure.init(rlc_h, log_h, timers);
|
||||||
phr_procedure.init(phy_h, log_h, timers);
|
phr_procedure.init(phy_h, log_h, timers);
|
||||||
mux_unit.init(rlc_h, &bsr_procedure, &phr_procedure);
|
mux_unit.init(rlc_h, &bsr_procedure, &phr_procedure);
|
||||||
demux_unit.init(phy_h, rlc_h, this, timers->get(timer_alignment));
|
demux_unit.init(phy_h, rlc_h, this, &timer_alignment);
|
||||||
ra_procedure.init(phy_h,
|
ra_procedure.init(
|
||||||
rrc,
|
phy_h, rrc, log_h, &uernti, &timer_alignment, std::move(contention_resolution_timer), &mux_unit, stack_h);
|
||||||
log_h,
|
|
||||||
&uernti,
|
|
||||||
timers->get(timer_alignment),
|
|
||||||
timers->get(contention_resolution_timer),
|
|
||||||
&mux_unit,
|
|
||||||
stack_h);
|
|
||||||
sr_procedure.init(phy_h, rrc, log_h);
|
sr_procedure.init(phy_h, rrc, log_h);
|
||||||
|
|
||||||
// Create UL/DL unique HARQ pointers
|
// Create UL/DL unique HARQ pointers
|
||||||
ul_harq.at(0)->init(log_h, &uernti, &ra_procedure, &mux_unit);
|
ul_harq.at(0)->init(log_h, &uernti, &ra_procedure, &mux_unit);
|
||||||
dl_harq.at(0)->init(log_h, &uernti, timers->get(timer_alignment), &demux_unit);
|
dl_harq.at(0)->init(log_h, &uernti, &timer_alignment, &demux_unit);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
|
@ -143,7 +137,7 @@ void mac::reconfiguration(const uint32_t& cc_idx, const bool& enable)
|
||||||
}
|
}
|
||||||
while (dl_harq.size() < cc_idx + 1) {
|
while (dl_harq.size() < cc_idx + 1) {
|
||||||
auto dl = dl_harq_entity_ptr(new dl_harq_entity());
|
auto dl = dl_harq_entity_ptr(new dl_harq_entity());
|
||||||
dl->init(log_h, &uernti, timers->get(timer_alignment), &demux_unit);
|
dl->init(log_h, &uernti, &timer_alignment, &demux_unit);
|
||||||
|
|
||||||
if (pcap) {
|
if (pcap) {
|
||||||
dl->start_pcap(pcap);
|
dl->start_pcap(pcap);
|
||||||
|
@ -170,7 +164,7 @@ void mac::reset()
|
||||||
|
|
||||||
Info("Resetting MAC\n");
|
Info("Resetting MAC\n");
|
||||||
|
|
||||||
timers->get(timer_alignment)->stop();
|
timer_alignment.stop();
|
||||||
|
|
||||||
timer_alignment_expire();
|
timer_alignment_expire();
|
||||||
|
|
||||||
|
@ -529,18 +523,18 @@ void mac::new_mch_dl(srslte_pdsch_grant_t phy_grant, tb_action_dl_t* action)
|
||||||
void mac::setup_timers(int time_alignment_timer)
|
void mac::setup_timers(int time_alignment_timer)
|
||||||
{
|
{
|
||||||
// stop currently running time alignment timer
|
// stop currently running time alignment timer
|
||||||
if (timers->get(timer_alignment)->is_running()) {
|
if (timer_alignment.is_running()) {
|
||||||
timers->get(timer_alignment)->stop();
|
timer_alignment.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (time_alignment_timer > 0) {
|
if (time_alignment_timer > 0) {
|
||||||
timers->get(timer_alignment)->set(this, time_alignment_timer);
|
timer_alignment.set(time_alignment_timer, [this](uint32_t tid) { timer_expired(tid); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mac::timer_expired(uint32_t timer_id)
|
void mac::timer_expired(uint32_t timer_id)
|
||||||
{
|
{
|
||||||
if(timer_id == timer_alignment) {
|
if (timer_id == timer_alignment.id()) {
|
||||||
timer_alignment_expire();
|
timer_alignment_expire();
|
||||||
} else {
|
} else {
|
||||||
Warning("Received callback from unknown timer_id=%d\n", timer_id);
|
Warning("Received callback from unknown timer_id=%d\n", timer_id);
|
||||||
|
@ -669,24 +663,4 @@ void mac::get_metrics(mac_metrics_t m[SRSLTE_MAX_CARRIERS])
|
||||||
bzero(&metrics, sizeof(mac_metrics_t) * SRSLTE_MAX_CARRIERS);
|
bzero(&metrics, sizeof(mac_metrics_t) * SRSLTE_MAX_CARRIERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
*
|
|
||||||
* Interface for timers used by upper layers
|
|
||||||
*
|
|
||||||
*******************************************************/
|
|
||||||
srslte::timers::timer* mac::timer_get(uint32_t timer_id)
|
|
||||||
{
|
|
||||||
return timers->get(timer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mac::timer_release_id(uint32_t timer_id)
|
|
||||||
{
|
|
||||||
timers->release_id(timer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t mac::timer_get_unique_id()
|
|
||||||
{
|
|
||||||
return timers->get_unique_id();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace srsue
|
} // namespace srsue
|
||||||
|
|
|
@ -42,14 +42,14 @@ bsr_proc::bsr_proc()
|
||||||
pthread_mutex_init(&mutex, NULL);
|
pthread_mutex_init(&mutex, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bsr_proc::init(rlc_interface_mac* rlc_, srslte::log* log_h_, srslte::timers* timers_db_)
|
void bsr_proc::init(rlc_interface_mac* rlc_, srslte::log* log_h_, srslte::timer_handler* timers_db_)
|
||||||
{
|
{
|
||||||
log_h = log_h_;
|
log_h = log_h_;
|
||||||
rlc = rlc_;
|
rlc = rlc_;
|
||||||
timers_db = timers_db_;
|
timers_db = timers_db_;
|
||||||
|
|
||||||
timer_periodic_id = timers_db->get_unique_id();
|
timer_periodic = timers_db->get_unique_timer();
|
||||||
timer_retx_id = timers_db->get_unique_id();
|
timer_retx = timers_db->get_unique_timer();
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
initiated = true;
|
initiated = true;
|
||||||
|
@ -63,13 +63,11 @@ void bsr_proc::set_trigger(srsue::bsr_proc::triggered_bsr_type_t new_trigger)
|
||||||
|
|
||||||
void bsr_proc::reset()
|
void bsr_proc::reset()
|
||||||
{
|
{
|
||||||
timers_db->get(timer_periodic_id)->stop();
|
timer_periodic.stop();
|
||||||
timers_db->get(timer_periodic_id)->reset();
|
timer_retx.stop();
|
||||||
timers_db->get(timer_retx_id)->stop();
|
|
||||||
timers_db->get(timer_retx_id)->reset();
|
|
||||||
|
|
||||||
reset_sr = false;
|
reset_sr = false;
|
||||||
sr_is_sent = false;
|
sr_is_sent = false;
|
||||||
triggered_bsr_type = NONE;
|
triggered_bsr_type = NONE;
|
||||||
|
|
||||||
trigger_tti = 0;
|
trigger_tti = 0;
|
||||||
|
@ -82,27 +80,28 @@ void bsr_proc::set_config(srslte::bsr_cfg_t& bsr_cfg)
|
||||||
this->bsr_cfg = bsr_cfg;
|
this->bsr_cfg = bsr_cfg;
|
||||||
|
|
||||||
if (bsr_cfg.periodic_timer > 0) {
|
if (bsr_cfg.periodic_timer > 0) {
|
||||||
timers_db->get(timer_periodic_id)->set(this, bsr_cfg.periodic_timer);
|
timer_periodic.set(bsr_cfg.periodic_timer, [this](uint32_t tid) { timer_expired(tid); });
|
||||||
Info("BSR: Configured timer periodic %d ms\n", bsr_cfg.periodic_timer);
|
Info("BSR: Configured timer periodic %d ms\n", bsr_cfg.periodic_timer);
|
||||||
}
|
}
|
||||||
if (bsr_cfg.retx_timer > 0) {
|
if (bsr_cfg.retx_timer > 0) {
|
||||||
timers_db->get(timer_retx_id)->set(this, bsr_cfg.retx_timer);
|
timer_retx.set(bsr_cfg.retx_timer, [this](uint32_t tid) { timer_expired(tid); });
|
||||||
Info("BSR: Configured timer reTX %d ms\n", bsr_cfg.retx_timer);
|
Info("BSR: Configured timer reTX %d ms\n", bsr_cfg.retx_timer);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Periodic BSR */
|
/* Process Periodic BSR */
|
||||||
void bsr_proc::timer_expired(uint32_t timer_id) {
|
void bsr_proc::timer_expired(uint32_t timer_id)
|
||||||
|
{
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
// periodicBSR-Timer
|
// periodicBSR-Timer
|
||||||
if (timer_id == timer_periodic_id) {
|
if (timer_id == timer_periodic.id()) {
|
||||||
if (triggered_bsr_type == NONE) {
|
if (triggered_bsr_type == NONE) {
|
||||||
set_trigger(PERIODIC);
|
set_trigger(PERIODIC);
|
||||||
Debug("BSR: Triggering Periodic BSR\n");
|
Debug("BSR: Triggering Periodic BSR\n");
|
||||||
}
|
}
|
||||||
// retxBSR-Timer
|
// retxBSR-Timer
|
||||||
} else if (timer_id == timer_retx_id) {
|
} else if (timer_id == timer_retx.id()) {
|
||||||
// Enable reTx of SR only if periodic timer is not infinity
|
// Enable reTx of SR only if periodic timer is not infinity
|
||||||
Debug("BSR: Timer BSR reTX expired, periodic=%d, channel=%d\n", bsr_cfg.periodic_timer, check_any_channel());
|
Debug("BSR: Timer BSR reTX expired, periodic=%d, channel=%d\n", bsr_cfg.periodic_timer, check_any_channel());
|
||||||
// Triger Regular BSR if UE has available data for transmission on any channel
|
// Triger Regular BSR if UE has available data for transmission on any channel
|
||||||
|
@ -243,13 +242,16 @@ bool bsr_proc::generate_bsr(bsr_t* bsr, uint32_t nof_padding_bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Info("BSR: Type %s, Format %s, Value=%d,%d,%d,%d\n",
|
Info("BSR: Type %s, Format %s, Value=%d,%d,%d,%d\n",
|
||||||
bsr_type_tostring(triggered_bsr_type), bsr_format_tostring(bsr->format),
|
bsr_type_tostring(triggered_bsr_type),
|
||||||
bsr->buff_size[0], bsr->buff_size[1], bsr->buff_size[2], bsr->buff_size[3]);
|
bsr_format_tostring(bsr->format),
|
||||||
|
bsr->buff_size[0],
|
||||||
|
bsr->buff_size[1],
|
||||||
|
bsr->buff_size[2],
|
||||||
|
bsr->buff_size[3]);
|
||||||
|
|
||||||
// Restart or Start Periodic timer every time a BSR is generated and transmitted in an UL grant
|
// Restart or Start Periodic timer every time a BSR is generated and transmitted in an UL grant
|
||||||
if (timers_db->get(timer_periodic_id)->get_timeout() && bsr->format != TRUNC_BSR) {
|
if (timer_periodic.duration() && bsr->format != TRUNC_BSR) {
|
||||||
timers_db->get(timer_periodic_id)->reset();
|
timer_periodic.run();
|
||||||
timers_db->get(timer_periodic_id)->run();
|
|
||||||
Debug("BSR: Started periodicBSR-Timer\n");
|
Debug("BSR: Started periodicBSR-Timer\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,9 +362,8 @@ bool bsr_proc::need_to_send_bsr_on_ul_grant(uint32_t grant_size, bsr_t* bsr)
|
||||||
reset_sr = true;
|
reset_sr = true;
|
||||||
|
|
||||||
// Restart or Start ReTX timer upon indication of a grant
|
// Restart or Start ReTX timer upon indication of a grant
|
||||||
if (timers_db->get(timer_retx_id)->get_timeout()) {
|
if (timer_retx.duration()) {
|
||||||
timers_db->get(timer_retx_id)->reset();
|
timer_retx.run();
|
||||||
timers_db->get(timer_retx_id)->run();
|
|
||||||
Debug("BSR: Started retxBSR-Timer\n");
|
Debug("BSR: Started retxBSR-Timer\n");
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
|
|
|
@ -38,24 +38,24 @@ phr_proc::phr_proc()
|
||||||
phr_cfg = {};
|
phr_cfg = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void phr_proc::init(phy_interface_mac_lte* phy_h_, srslte::log* log_h_, srslte::timers* timers_db_)
|
void phr_proc::init(phy_interface_mac_lte* phy_h_, srslte::log* log_h_, srslte::timer_handler* timers_db_)
|
||||||
{
|
{
|
||||||
phy_h = phy_h_;
|
phy_h = phy_h_;
|
||||||
log_h = log_h_;
|
log_h = log_h_;
|
||||||
timers_db = timers_db_;
|
timers_db = timers_db_;
|
||||||
initiated = true;
|
initiated = true;
|
||||||
|
|
||||||
timer_periodic_id = timers_db->get_unique_id();
|
timer_periodic = timers_db->get_unique_timer();
|
||||||
timer_prohibit_id = timers_db->get_unique_id();
|
timer_prohibit = timers_db->get_unique_timer();
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void phr_proc::reset()
|
void phr_proc::reset()
|
||||||
{
|
{
|
||||||
timers_db->get(timer_periodic_id)->stop();
|
timer_periodic.stop();
|
||||||
timers_db->get(timer_prohibit_id)->stop();
|
timer_prohibit.stop();
|
||||||
phr_is_triggered = false;
|
phr_is_triggered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void phr_proc::set_config(srslte::phr_cfg_t& cfg)
|
void phr_proc::set_config(srslte::phr_cfg_t& cfg)
|
||||||
|
@ -63,21 +63,21 @@ void phr_proc::set_config(srslte::phr_cfg_t& cfg)
|
||||||
phr_cfg = cfg;
|
phr_cfg = cfg;
|
||||||
|
|
||||||
// First stop timers. If enabled==false or value is Inf, won't be re-started
|
// First stop timers. If enabled==false or value is Inf, won't be re-started
|
||||||
timers_db->get(timer_periodic_id)->stop();
|
timer_periodic.stop();
|
||||||
timers_db->get(timer_prohibit_id)->stop();
|
timer_prohibit.stop();
|
||||||
|
|
||||||
if (cfg.enabled) {
|
if (cfg.enabled) {
|
||||||
// Setup timers and trigger PHR when configuration changed by higher layers
|
// Setup timers and trigger PHR when configuration changed by higher layers
|
||||||
if (phr_cfg.periodic_timer > 0) {
|
if (phr_cfg.periodic_timer > 0) {
|
||||||
timers_db->get(timer_periodic_id)->set(this, phr_cfg.periodic_timer);
|
timer_periodic.set(phr_cfg.periodic_timer, [this](uint32_t tid) { timer_expired(tid); });
|
||||||
timers_db->get(timer_periodic_id)->run();
|
timer_periodic.run();
|
||||||
phr_is_triggered = true;
|
phr_is_triggered = true;
|
||||||
Info("PHR: Configured timer periodic %d ms\n", phr_cfg.periodic_timer);
|
Info("PHR: Configured timer periodic %d ms\n", phr_cfg.periodic_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phr_cfg.prohibit_timer > 0) {
|
if (phr_cfg.prohibit_timer > 0) {
|
||||||
timers_db->get(timer_prohibit_id)->set(this, phr_cfg.prohibit_timer);
|
timer_prohibit.set(phr_cfg.prohibit_timer, [this](uint32_t tid) { timer_expired(tid); });
|
||||||
timers_db->get(timer_prohibit_id)->run();
|
timer_prohibit.run();
|
||||||
Info("PHR: Configured timer prohibit %d ms\n", phr_cfg.prohibit_timer);
|
Info("PHR: Configured timer prohibit %d ms\n", phr_cfg.prohibit_timer);
|
||||||
phr_is_triggered = true;
|
phr_is_triggered = true;
|
||||||
}
|
}
|
||||||
|
@ -99,22 +99,23 @@ bool phr_proc::pathloss_changed() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void phr_proc::start_timer() {
|
void phr_proc::start_timer()
|
||||||
timers_db->get(timer_periodic_id)->run();
|
{
|
||||||
|
timer_periodic.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trigger PHR when timers exires */
|
/* Trigger PHR when timers exires */
|
||||||
void phr_proc::timer_expired(uint32_t timer_id) {
|
void phr_proc::timer_expired(uint32_t timer_id)
|
||||||
|
{
|
||||||
if (!phr_cfg.enabled) {
|
if (!phr_cfg.enabled) {
|
||||||
Warning("PHR: Timer triggered but PHR has been disabled\n");
|
Warning("PHR: Timer triggered but PHR has been disabled\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (timer_id == timer_periodic_id) {
|
if (timer_id == timer_periodic.id()) {
|
||||||
timers_db->get(timer_periodic_id)->reset();
|
timer_periodic.run();
|
||||||
timers_db->get(timer_periodic_id)->run();
|
|
||||||
Debug("PHR: Triggered by timer periodic (timer expired).\n");
|
Debug("PHR: Triggered by timer periodic (timer expired).\n");
|
||||||
phr_is_triggered = true;
|
phr_is_triggered = true;
|
||||||
} else if (timer_id == timer_prohibit_id) {
|
} else if (timer_id == timer_prohibit.id()) {
|
||||||
if (pathloss_changed()) {
|
if (pathloss_changed()) {
|
||||||
Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d (timer expired)\n", last_pathloss_db);
|
Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d (timer expired)\n", last_pathloss_db);
|
||||||
phr_is_triggered = true;
|
phr_is_triggered = true;
|
||||||
|
@ -127,14 +128,14 @@ void phr_proc::timer_expired(uint32_t timer_id) {
|
||||||
void phr_proc::step(uint32_t tti)
|
void phr_proc::step(uint32_t tti)
|
||||||
{
|
{
|
||||||
if (phr_cfg.enabled && initiated) {
|
if (phr_cfg.enabled && initiated) {
|
||||||
if (pathloss_changed() && timers_db->get(timer_prohibit_id)->is_expired()) {
|
if (pathloss_changed() && timer_prohibit.is_expired()) {
|
||||||
Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d\n", last_pathloss_db);
|
Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d\n", last_pathloss_db);
|
||||||
phr_is_triggered = true;
|
phr_is_triggered = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool phr_proc::generate_phr_on_ul_grant(float *phr)
|
bool phr_proc::generate_phr_on_ul_grant(float* phr)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (phr_is_triggered) {
|
if (phr_is_triggered) {
|
||||||
|
@ -142,12 +143,10 @@ bool phr_proc::generate_phr_on_ul_grant(float *phr)
|
||||||
*phr = phy_h->get_phr();
|
*phr = phy_h->get_phr();
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug("PHR: Generating PHR=%f\n", phr?*phr:0.0);
|
Debug("PHR: Generating PHR=%f\n", phr ? *phr : 0.0);
|
||||||
|
|
||||||
timers_db->get(timer_periodic_id)->reset();
|
timer_periodic.run();
|
||||||
timers_db->get(timer_prohibit_id)->reset();
|
timer_prohibit.run();
|
||||||
timers_db->get(timer_periodic_id)->run();
|
|
||||||
timers_db->get(timer_prohibit_id)->run();
|
|
||||||
|
|
||||||
phr_is_triggered = false;
|
phr_is_triggered = false;
|
||||||
|
|
||||||
|
|
|
@ -56,14 +56,14 @@ uint32_t backoff_table[16] = {0, 10, 20, 30, 40, 60, 80, 120, 160, 240, 320, 480
|
||||||
int delta_preamble_db_table[5] = {0, 0, -3, -3, 8};
|
int delta_preamble_db_table[5] = {0, 0, -3, -3, 8};
|
||||||
|
|
||||||
// Initializes memory and pointers to other objects
|
// Initializes memory and pointers to other objects
|
||||||
void ra_proc::init(phy_interface_mac_lte* phy_h_,
|
void ra_proc::init(phy_interface_mac_lte* phy_h_,
|
||||||
rrc_interface_mac* rrc_,
|
rrc_interface_mac* rrc_,
|
||||||
srslte::log* log_h_,
|
srslte::log* log_h_,
|
||||||
mac_interface_rrc::ue_rnti_t* rntis_,
|
mac_interface_rrc::ue_rnti_t* rntis_,
|
||||||
srslte::timers::timer* time_alignment_timer_,
|
srslte::timer_handler::unique_timer* time_alignment_timer_,
|
||||||
srslte::timers::timer* contention_resolution_timer_,
|
srslte::timer_handler::unique_timer contention_resolution_timer_,
|
||||||
mux* mux_unit_,
|
mux* mux_unit_,
|
||||||
stack_interface_mac* stack_)
|
stack_interface_mac* stack_)
|
||||||
{
|
{
|
||||||
phy_h = phy_h_;
|
phy_h = phy_h_;
|
||||||
log_h = log_h_;
|
log_h = log_h_;
|
||||||
|
@ -73,22 +73,23 @@ void ra_proc::init(phy_interface_mac_lte* phy_h_,
|
||||||
stack = stack_;
|
stack = stack_;
|
||||||
|
|
||||||
time_alignment_timer = time_alignment_timer_;
|
time_alignment_timer = time_alignment_timer_;
|
||||||
contention_resolution_timer = contention_resolution_timer_;
|
contention_resolution_timer = std::move(contention_resolution_timer_);
|
||||||
|
|
||||||
srslte_softbuffer_rx_init(&softbuffer_rar, 10);
|
srslte_softbuffer_rx_init(&softbuffer_rar, 10);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
ra_proc::~ra_proc() {
|
ra_proc::~ra_proc()
|
||||||
|
{
|
||||||
srslte_softbuffer_rx_free(&softbuffer_rar);
|
srslte_softbuffer_rx_free(&softbuffer_rar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ra_proc::reset() {
|
void ra_proc::reset()
|
||||||
state = IDLE;
|
{
|
||||||
|
state = IDLE;
|
||||||
started_by_pdcch = false;
|
started_by_pdcch = false;
|
||||||
contention_resolution_timer->stop();
|
contention_resolution_timer.stop();
|
||||||
contention_resolution_timer->reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ra_proc::start_pcap(srslte::mac_pcap* pcap_)
|
void ra_proc::start_pcap(srslte::mac_pcap* pcap_)
|
||||||
|
@ -125,10 +126,10 @@ void ra_proc::read_params()
|
||||||
}
|
}
|
||||||
|
|
||||||
phy_interface_mac_lte::prach_info_t prach_info = phy_h->prach_get_info();
|
phy_interface_mac_lte::prach_info_t prach_info = phy_h->prach_get_info();
|
||||||
delta_preamble_db = delta_preamble_db_table[prach_info.preamble_format % 5];
|
delta_preamble_db = delta_preamble_db_table[prach_info.preamble_format % 5];
|
||||||
|
|
||||||
if (rach_cfg.contentionResolutionTimer > 0) {
|
if (rach_cfg.contentionResolutionTimer > 0) {
|
||||||
contention_resolution_timer->set(this, rach_cfg.contentionResolutionTimer);
|
contention_resolution_timer.set(rach_cfg.contentionResolutionTimer, [this](uint32_t tid) { timer_expired(tid); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,11 +223,10 @@ void ra_proc::state_backoff_wait(uint32_t tti)
|
||||||
void ra_proc::state_contention_resolution()
|
void ra_proc::state_contention_resolution()
|
||||||
{
|
{
|
||||||
// Once Msg3 is transmitted, start contention resolution timer
|
// Once Msg3 is transmitted, start contention resolution timer
|
||||||
if (mux_unit->msg3_is_transmitted() && !contention_resolution_timer->is_running()) {
|
if (mux_unit->msg3_is_transmitted() && !contention_resolution_timer.is_running()) {
|
||||||
// Start contention resolution timer
|
// Start contention resolution timer
|
||||||
rInfo("Starting ContentionResolutionTimer=%d ms\n", contention_resolution_timer->get_timeout());
|
rInfo("Starting ContentionResolutionTimer=%d ms\n", contention_resolution_timer.duration());
|
||||||
contention_resolution_timer->reset();
|
contention_resolution_timer.run();
|
||||||
contention_resolution_timer->run();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +350,6 @@ void ra_proc::process_timeadv_cmd(uint32_t ta)
|
||||||
phy_h->set_timeadv_rar(ta);
|
phy_h->set_timeadv_rar(ta);
|
||||||
// Only if timer is running reset the timer
|
// Only if timer is running reset the timer
|
||||||
if (time_alignment_timer->is_running()) {
|
if (time_alignment_timer->is_running()) {
|
||||||
time_alignment_timer->reset();
|
|
||||||
time_alignment_timer->run();
|
time_alignment_timer->run();
|
||||||
}
|
}
|
||||||
Debug("Applying RAR TA CMD %d\n", ta);
|
Debug("Applying RAR TA CMD %d\n", ta);
|
||||||
|
@ -574,7 +573,7 @@ bool ra_proc::contention_resolution_id_received(uint64_t rx_contention_id)
|
||||||
rDebug("MAC PDU Contains Contention Resolution ID CE\n");
|
rDebug("MAC PDU Contains Contention Resolution ID CE\n");
|
||||||
|
|
||||||
// MAC PDU successfully decoded and contains MAC CE contention Id
|
// MAC PDU successfully decoded and contains MAC CE contention Id
|
||||||
contention_resolution_timer->stop();
|
contention_resolution_timer.stop();
|
||||||
|
|
||||||
if (transmitted_contention_id == rx_contention_id) {
|
if (transmitted_contention_id == rx_contention_id) {
|
||||||
// UE Contention Resolution ID included in MAC CE matches the CCCH SDU transmitted in Msg3
|
// UE Contention Resolution ID included in MAC CE matches the CCCH SDU transmitted in Msg3
|
||||||
|
@ -600,7 +599,7 @@ void ra_proc::pdcch_to_crnti(bool is_new_uplink_transmission)
|
||||||
rDebug("PDCCH to C-RNTI received %s new UL transmission\n", is_new_uplink_transmission ? "with" : "without");
|
rDebug("PDCCH to C-RNTI received %s new UL transmission\n", is_new_uplink_transmission ? "with" : "without");
|
||||||
if ((!started_by_pdcch && is_new_uplink_transmission) || started_by_pdcch) {
|
if ((!started_by_pdcch && is_new_uplink_transmission) || started_by_pdcch) {
|
||||||
rDebug("PDCCH for C-RNTI received\n");
|
rDebug("PDCCH for C-RNTI received\n");
|
||||||
contention_resolution_timer->stop();
|
contention_resolution_timer.stop();
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -626,8 +625,8 @@ bool ra_proc::update_rar_window(int* rar_window_start, int* rar_window_length)
|
||||||
// Restart timer at each Msg3 HARQ retransmission (5.1.5)
|
// Restart timer at each Msg3 HARQ retransmission (5.1.5)
|
||||||
void ra_proc::harq_retx()
|
void ra_proc::harq_retx()
|
||||||
{
|
{
|
||||||
rInfo("Restarting ContentionResolutionTimer=%d ms\n", contention_resolution_timer->get_timeout());
|
rInfo("Restarting ContentionResolutionTimer=%d ms\n", contention_resolution_timer.duration());
|
||||||
contention_resolution_timer->reset();
|
contention_resolution_timer.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ra_proc::harq_max_retx()
|
void ra_proc::harq_max_retx()
|
||||||
|
|
|
@ -107,7 +107,7 @@ void rrc::init(phy_interface_rrc_lte* phy_,
|
||||||
nas_interface_rrc* nas_,
|
nas_interface_rrc* nas_,
|
||||||
usim_interface_rrc* usim_,
|
usim_interface_rrc* usim_,
|
||||||
gw_interface_rrc* gw_,
|
gw_interface_rrc* gw_,
|
||||||
srslte::timers* timers_,
|
srslte::timer_handler* timers_,
|
||||||
stack_interface_rrc* stack_,
|
stack_interface_rrc* stack_,
|
||||||
const rrc_args_t& args_)
|
const rrc_args_t& args_)
|
||||||
{
|
{
|
||||||
|
@ -130,12 +130,12 @@ void rrc::init(phy_interface_rrc_lte* phy_,
|
||||||
|
|
||||||
security_is_activated = false;
|
security_is_activated = false;
|
||||||
|
|
||||||
t300 = timers->get_unique_id();
|
t300 = timers->get_unique_timer();
|
||||||
t301 = timers->get_unique_id();
|
t301 = timers->get_unique_timer();
|
||||||
t302 = timers->get_unique_id();
|
t302 = timers->get_unique_timer();
|
||||||
t310 = timers->get_unique_id();
|
t310 = timers->get_unique_timer();
|
||||||
t311 = timers->get_unique_id();
|
t311 = timers->get_unique_timer();
|
||||||
t304 = timers->get_unique_id();
|
t304 = timers->get_unique_timer();
|
||||||
|
|
||||||
ue_identity_configured = false;
|
ue_identity_configured = false;
|
||||||
|
|
||||||
|
@ -434,20 +434,17 @@ void rrc::out_of_sync()
|
||||||
// upon receiving N310 consecutive "out-of-sync" indications for the PCell from lower layers while neither T300,
|
// upon receiving N310 consecutive "out-of-sync" indications for the PCell from lower layers while neither T300,
|
||||||
// T301, T304 nor T311 is running:
|
// T301, T304 nor T311 is running:
|
||||||
if (state == RRC_STATE_CONNECTED) {
|
if (state == RRC_STATE_CONNECTED) {
|
||||||
if (!timers->get(t300)->is_running() && !timers->get(t301)->is_running() && !timers->get(t304)->is_running() &&
|
if (!t300.is_running() && !t301.is_running() && !t304.is_running() && !t310.is_running() && !t311.is_running()) {
|
||||||
!timers->get(t310)->is_running() && !timers->get(t311)->is_running()) {
|
|
||||||
rrc_log->info("Received out-of-sync while in state %s. n310=%d, t311=%s, t310=%s\n",
|
rrc_log->info("Received out-of-sync while in state %s. n310=%d, t311=%s, t310=%s\n",
|
||||||
rrc_state_text[state],
|
rrc_state_text[state],
|
||||||
n310_cnt,
|
n310_cnt,
|
||||||
timers->get(t311)->is_running() ? "running" : "stop",
|
t311.is_running() ? "running" : "stop",
|
||||||
timers->get(t310)->is_running() ? "running" : "stop");
|
t310.is_running() ? "running" : "stop");
|
||||||
n310_cnt++;
|
n310_cnt++;
|
||||||
if (n310_cnt == N310) {
|
if (n310_cnt == N310) {
|
||||||
rrc_log->info("Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer %d ms\n",
|
rrc_log->info(
|
||||||
N310,
|
"Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer %d ms\n", N310, t310.duration());
|
||||||
timers->get(t310)->get_timeout());
|
t310.run();
|
||||||
timers->get(t310)->reset();
|
|
||||||
timers->get(t310)->run();
|
|
||||||
n310_cnt = 0;
|
n310_cnt = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -460,10 +457,10 @@ void rrc::in_sync()
|
||||||
{
|
{
|
||||||
// CAUTION: We do not lock in this function since they are called from real-time threads
|
// CAUTION: We do not lock in this function since they are called from real-time threads
|
||||||
serving_cell->in_sync = true;
|
serving_cell->in_sync = true;
|
||||||
if (timers->get(t310)->is_running()) {
|
if (t310.is_running()) {
|
||||||
n311_cnt++;
|
n311_cnt++;
|
||||||
if (n311_cnt == N311) {
|
if (n311_cnt == N311) {
|
||||||
timers->get(t310)->stop();
|
t310.stop();
|
||||||
n311_cnt = 0;
|
n311_cnt = 0;
|
||||||
rrc_log->info("Detected %d in-sync from PHY. Stopping T310 timer\n", N311);
|
rrc_log->info("Detected %d in-sync from PHY. Stopping T310 timer\n", N311);
|
||||||
}
|
}
|
||||||
|
@ -819,50 +816,44 @@ void rrc::max_retx_attempted() {
|
||||||
cmd_q.push(std::move(msg));
|
cmd_q.push(std::move(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void rrc::timer_expired(uint32_t timeout_id) {
|
void rrc::timer_expired(uint32_t timeout_id)
|
||||||
if (timeout_id == t310) {
|
{
|
||||||
|
if (timeout_id == t310.id()) {
|
||||||
rrc_log->info("Timer T310 expired: Radio Link Failure\n");
|
rrc_log->info("Timer T310 expired: Radio Link Failure\n");
|
||||||
radio_link_failure();
|
radio_link_failure();
|
||||||
} else if (timeout_id == t311) {
|
} else if (timeout_id == t311.id()) {
|
||||||
rrc_log->info("Timer T311 expired: Going to RRC IDLE\n");
|
rrc_log->info("Timer T311 expired: Going to RRC IDLE\n");
|
||||||
start_go_idle();
|
start_go_idle();
|
||||||
} else if (timeout_id == t301) {
|
} else if (timeout_id == t301.id()) {
|
||||||
if (state == RRC_STATE_IDLE) {
|
if (state == RRC_STATE_IDLE) {
|
||||||
rrc_log->info("Timer T301 expired: Already in IDLE.\n");
|
rrc_log->info("Timer T301 expired: Already in IDLE.\n");
|
||||||
} else {
|
} else {
|
||||||
rrc_log->info("Timer T301 expired: Going to RRC IDLE\n");
|
rrc_log->info("Timer T301 expired: Going to RRC IDLE\n");
|
||||||
start_go_idle();
|
start_go_idle();
|
||||||
}
|
}
|
||||||
} else if (timeout_id == t302) {
|
} else if (timeout_id == t302.id()) {
|
||||||
rrc_log->info("Timer T302 expired. Informing NAS about barrier alleviation\n");
|
rrc_log->info("Timer T302 expired. Informing NAS about barrier alleviation\n");
|
||||||
nas->set_barring(nas_interface_rrc::BARRING_NONE);
|
nas->set_barring(nas_interface_rrc::BARRING_NONE);
|
||||||
} else if (timeout_id == t300) {
|
} else if (timeout_id == t300.id()) {
|
||||||
// Do nothing, handled in connection_request()
|
// Do nothing, handled in connection_request()
|
||||||
} else if (timeout_id == t304) {
|
} else if (timeout_id == t304.id()) {
|
||||||
rrc_log->console("Timer T304 expired: Handover failed\n");
|
rrc_log->console("Timer T304 expired: Handover failed\n");
|
||||||
ho_failed();
|
ho_failed();
|
||||||
// fw to measurement
|
// fw to measurement
|
||||||
} else if (!measurements.timer_expired(timeout_id)) {
|
} else if (!measurements.timer_expired(timeout_id)) {
|
||||||
rrc_log->error("Timeout from unknown timer id %d\n", timeout_id);
|
rrc_log->error("Timeout from unknown timer id %d\n", timeout_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Connection Control: Establishment, Reconfiguration, Reestablishment and Release
|
* Connection Control: Establishment, Reconfiguration, Reestablishment and Release
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
void rrc::send_con_request(srslte::establishment_cause_t cause)
|
void rrc::send_con_request(srslte::establishment_cause_t cause)
|
||||||
{
|
{
|
||||||
|
@ -1067,8 +1058,8 @@ bool rrc::ho_prepare()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Section 5.3.5.4
|
// Section 5.3.5.4
|
||||||
timers->get(t310)->stop();
|
t310.stop();
|
||||||
timers->get(t304)->set(this, mob_ctrl_info->t304.to_number());
|
t304.set(mob_ctrl_info->t304.to_number(), [this](uint32_t tid) { timer_expired(tid); });
|
||||||
|
|
||||||
// Save serving cell and current configuration
|
// Save serving cell and current configuration
|
||||||
ho_src_cell = *serving_cell;
|
ho_src_cell = *serving_cell;
|
||||||
|
@ -1153,12 +1144,12 @@ void rrc::ho_ra_completed(bool ra_successful)
|
||||||
measurements.parse_meas_config(&mob_reconf_r8->meas_cfg);
|
measurements.parse_meas_config(&mob_reconf_r8->meas_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
timers->get(t304)->stop();
|
t304.stop();
|
||||||
}
|
}
|
||||||
// T304 will expiry and send ho_failure
|
// T304 will expiry and send ho_failure
|
||||||
|
|
||||||
rrc_log->info("HO %ssuccessful\n", ra_successful?"":"un");
|
rrc_log->info("HO %ssuccessful\n", ra_successful ? "" : "un");
|
||||||
rrc_log->console("HO %ssuccessful\n", ra_successful?"":"un");
|
rrc_log->console("HO %ssuccessful\n", ra_successful ? "" : "un");
|
||||||
|
|
||||||
pending_mob_reconf = false;
|
pending_mob_reconf = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1348,11 +1339,11 @@ void rrc::leave_connected()
|
||||||
|
|
||||||
void rrc::stop_timers()
|
void rrc::stop_timers()
|
||||||
{
|
{
|
||||||
timers->get(t300)->stop();
|
t300.stop();
|
||||||
timers->get(t301)->stop();
|
t301.stop();
|
||||||
timers->get(t310)->stop();
|
t310.stop();
|
||||||
timers->get(t311)->stop();
|
t311.stop();
|
||||||
timers->get(t304)->stop();
|
t304.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of procedure in 3GPP 36.331 Section 5.3.7.2: Initiation
|
/* Implementation of procedure in 3GPP 36.331 Section 5.3.7.2: Initiation
|
||||||
|
@ -1402,11 +1393,10 @@ void rrc::proc_con_restablish_request()
|
||||||
rrc_log->info("Resetting timers and MAC in RRC Connection Reestablishment Procedure\n");
|
rrc_log->info("Resetting timers and MAC in RRC Connection Reestablishment Procedure\n");
|
||||||
|
|
||||||
// stop timer T310, if running;
|
// stop timer T310, if running;
|
||||||
timers->get(t310)->stop();
|
t310.stop();
|
||||||
|
|
||||||
// start timer T311;
|
// start timer T311;
|
||||||
timers->get(t311)->reset();
|
t311.run();
|
||||||
timers->get(t311)->run();
|
|
||||||
|
|
||||||
// Suspend all RB except SRB0
|
// Suspend all RB except SRB0
|
||||||
for (int i = 1; i < SRSLTE_N_RADIO_BEARERS; i++) {
|
for (int i = 1; i < SRSLTE_N_RADIO_BEARERS; i++) {
|
||||||
|
@ -1432,7 +1422,7 @@ void rrc::proc_con_restablish_request()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check timer...
|
// Check timer...
|
||||||
if (timers->get(t311)->is_running()) {
|
if (t311.is_running()) {
|
||||||
// Wait until we're synced and have obtained SIBs
|
// Wait until we're synced and have obtained SIBs
|
||||||
if (serving_cell->in_sync && serving_cell->has_sib1() && serving_cell->has_sib2() && serving_cell->has_sib3()) {
|
if (serving_cell->in_sync && serving_cell->has_sib1() && serving_cell->has_sib2() && serving_cell->has_sib3()) {
|
||||||
// Perform cell selection in accordance to 36.304
|
// Perform cell selection in accordance to 36.304
|
||||||
|
@ -1440,16 +1430,16 @@ void rrc::proc_con_restablish_request()
|
||||||
// Actions following cell reselection while T311 is running 5.3.7.3
|
// Actions following cell reselection while T311 is running 5.3.7.3
|
||||||
// Upon selecting a suitable E-UTRA cell, the UE shall:
|
// Upon selecting a suitable E-UTRA cell, the UE shall:
|
||||||
rrc_log->info("Cell Selection criteria passed after %dms. Sending RRC Connection Reestablishment Request\n",
|
rrc_log->info("Cell Selection criteria passed after %dms. Sending RRC Connection Reestablishment Request\n",
|
||||||
timers->get(t311)->value());
|
t311.value());
|
||||||
|
|
||||||
// stop timer T311;
|
// stop timer T311;
|
||||||
timers->get(t301)->reset();
|
t311.stop();
|
||||||
|
|
||||||
// start timer T301;
|
// start timer T301;
|
||||||
timers->get(t301)->run();
|
t301.run();
|
||||||
|
|
||||||
// apply the timeAlignmentTimerCommon included in SystemInformationBlockType2;
|
// apply the timeAlignmentTimerCommon included in SystemInformationBlockType2;
|
||||||
timers->get(t311)->stop();
|
// TODO
|
||||||
|
|
||||||
// initiate transmission of the RRCConnectionReestablishmentRequest message in accordance with 5.3.7.4;
|
// initiate transmission of the RRCConnectionReestablishmentRequest message in accordance with 5.3.7.4;
|
||||||
send_con_restablish_request();
|
send_con_restablish_request();
|
||||||
|
@ -1659,20 +1649,21 @@ void rrc::handle_sib2()
|
||||||
|
|
||||||
log_rr_config_common();
|
log_rr_config_common();
|
||||||
|
|
||||||
timers->get(t300)->set(this, sib2->ue_timers_and_consts.t300.to_number());
|
auto timer_expire_func = [this](uint32_t tid) { timer_expired(tid); };
|
||||||
timers->get(t301)->set(this, sib2->ue_timers_and_consts.t301.to_number());
|
t300.set(sib2->ue_timers_and_consts.t300.to_number(), timer_expire_func);
|
||||||
timers->get(t310)->set(this, sib2->ue_timers_and_consts.t310.to_number());
|
t301.set(sib2->ue_timers_and_consts.t301.to_number(), timer_expire_func);
|
||||||
timers->get(t311)->set(this, sib2->ue_timers_and_consts.t311.to_number());
|
t310.set(sib2->ue_timers_and_consts.t310.to_number(), timer_expire_func);
|
||||||
|
t311.set(sib2->ue_timers_and_consts.t311.to_number(), timer_expire_func);
|
||||||
N310 = sib2->ue_timers_and_consts.n310.to_number();
|
N310 = sib2->ue_timers_and_consts.n310.to_number();
|
||||||
N311 = sib2->ue_timers_and_consts.n311.to_number();
|
N311 = sib2->ue_timers_and_consts.n311.to_number();
|
||||||
|
|
||||||
rrc_log->info("Set Constants and Timers: N310=%d, N311=%d, t300=%d, t301=%d, t310=%d, t311=%d\n",
|
rrc_log->info("Set Constants and Timers: N310=%d, N311=%d, t300=%d, t301=%d, t310=%d, t311=%d\n",
|
||||||
N310,
|
N310,
|
||||||
N311,
|
N311,
|
||||||
timers->get(t300)->get_timeout(),
|
t300.duration(),
|
||||||
timers->get(t301)->get_timeout(),
|
t301.duration(),
|
||||||
timers->get(t310)->get_timeout(),
|
t310.duration(),
|
||||||
timers->get(t311)->get_timeout());
|
t311.duration());
|
||||||
}
|
}
|
||||||
|
|
||||||
void rrc::handle_sib3()
|
void rrc::handle_sib3()
|
||||||
|
@ -1914,12 +1905,12 @@ void rrc::parse_dl_ccch(unique_byte_buffer_t pdu)
|
||||||
rrc_log->info("Received ConnectionReject. Wait time: %d\n", reject_r8->wait_time);
|
rrc_log->info("Received ConnectionReject. Wait time: %d\n", reject_r8->wait_time);
|
||||||
rrc_log->console("Received ConnectionReject. Wait time: %d\n", reject_r8->wait_time);
|
rrc_log->console("Received ConnectionReject. Wait time: %d\n", reject_r8->wait_time);
|
||||||
|
|
||||||
timers->get(t300)->stop();
|
t300.stop();
|
||||||
|
|
||||||
if (reject_r8->wait_time) {
|
if (reject_r8->wait_time) {
|
||||||
nas->set_barring(nas_interface_rrc::BARRING_ALL);
|
nas->set_barring(nas_interface_rrc::BARRING_ALL);
|
||||||
timers->get(t302)->set(this, reject_r8->wait_time * 1000u);
|
t302.set(reject_r8->wait_time * 1000, [this](uint32_t tid) { timer_expired(tid); });
|
||||||
timers->get(t302)->run();
|
t302.run();
|
||||||
} else {
|
} else {
|
||||||
// Perform the actions upon expiry of T302 if wait time is zero
|
// Perform the actions upon expiry of T302 if wait time is zero
|
||||||
nas->set_barring(nas_interface_rrc::BARRING_NONE);
|
nas->set_barring(nas_interface_rrc::BARRING_NONE);
|
||||||
|
@ -2543,19 +2534,20 @@ bool rrc::apply_rr_config_dedicated(rr_cfg_ded_s* cnfg)
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
if (cnfg->rlf_timers_and_consts_r9.is_present() and cnfg->rlf_timers_and_consts_r9->type() == setup_e::setup) {
|
if (cnfg->rlf_timers_and_consts_r9.is_present() and cnfg->rlf_timers_and_consts_r9->type() == setup_e::setup) {
|
||||||
timers->get(t301)->set(this, cnfg->rlf_timers_and_consts_r9->setup().t301_r9.to_number());
|
auto timer_expire_func = [this](uint32_t tid) { timer_expired(tid); };
|
||||||
timers->get(t310)->set(this, cnfg->rlf_timers_and_consts_r9->setup().t310_r9.to_number());
|
t301.set(cnfg->rlf_timers_and_consts_r9->setup().t301_r9.to_number(), timer_expire_func);
|
||||||
timers->get(t311)->set(this, cnfg->rlf_timers_and_consts_r9->setup().t311_r9.to_number());
|
t310.set(cnfg->rlf_timers_and_consts_r9->setup().t310_r9.to_number(), timer_expire_func);
|
||||||
|
t311.set(cnfg->rlf_timers_and_consts_r9->setup().t311_r9.to_number(), timer_expire_func);
|
||||||
N310 = cnfg->rlf_timers_and_consts_r9->setup().n310_r9.to_number();
|
N310 = cnfg->rlf_timers_and_consts_r9->setup().n310_r9.to_number();
|
||||||
N311 = cnfg->rlf_timers_and_consts_r9->setup().n311_r9.to_number();
|
N311 = cnfg->rlf_timers_and_consts_r9->setup().n311_r9.to_number();
|
||||||
|
|
||||||
rrc_log->info("Updated Constants and Timers: N310=%d, N311=%d, t300=%u, t301=%u, t310=%u, t311=%u\n",
|
rrc_log->info("Updated Constants and Timers: N310=%d, N311=%d, t300=%u, t301=%u, t310=%u, t311=%u\n",
|
||||||
N310,
|
N310,
|
||||||
N311,
|
N311,
|
||||||
timers->get(t300)->get_timeout(),
|
t300.duration(),
|
||||||
timers->get(t301)->get_timeout(),
|
t301.duration(),
|
||||||
timers->get(t310)->get_timeout(),
|
t310.duration(),
|
||||||
timers->get(t311)->get_timeout());
|
t311.duration());
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < cnfg->srb_to_add_mod_list.size(); i++) {
|
for (uint32_t i = 0; i < cnfg->srb_to_add_mod_list.size(); i++) {
|
||||||
// TODO: handle SRB modification
|
// TODO: handle SRB modification
|
||||||
|
@ -2635,8 +2627,8 @@ void rrc::handle_con_setup(rrc_conn_setup_s* setup)
|
||||||
{
|
{
|
||||||
// Must enter CONNECT before stopping T300
|
// Must enter CONNECT before stopping T300
|
||||||
state = RRC_STATE_CONNECTED;
|
state = RRC_STATE_CONNECTED;
|
||||||
timers->get(t300)->stop();
|
t300.stop();
|
||||||
timers->get(t302)->stop();
|
t302.stop();
|
||||||
rrc_log->console("RRC Connected\n");
|
rrc_log->console("RRC Connected\n");
|
||||||
|
|
||||||
// Apply the Radio Resource configuration
|
// Apply the Radio Resource configuration
|
||||||
|
@ -2654,7 +2646,7 @@ void rrc::handle_con_setup(rrc_conn_setup_s* setup)
|
||||||
/* Reception of RRCConnectionReestablishment by the UE 5.3.7.5 */
|
/* Reception of RRCConnectionReestablishment by the UE 5.3.7.5 */
|
||||||
void rrc::handle_con_reest(rrc_conn_reest_s* setup)
|
void rrc::handle_con_reest(rrc_conn_reest_s* setup)
|
||||||
{
|
{
|
||||||
timers->get(t301)->stop();
|
t301.stop();
|
||||||
|
|
||||||
// Reestablish PDCP and RLC for SRB1
|
// Reestablish PDCP and RLC for SRB1
|
||||||
pdcp->reestablish(1);
|
pdcp->reestablish(1);
|
||||||
|
@ -2848,10 +2840,11 @@ void rrc::set_mac_default() {
|
||||||
|
|
||||||
void rrc::set_rrc_default()
|
void rrc::set_rrc_default()
|
||||||
{
|
{
|
||||||
N310 = 1;
|
N310 = 1;
|
||||||
N311 = 1;
|
N311 = 1;
|
||||||
timers->get(t310)->set(this, 1000);
|
auto timer_expire_func = [this](uint32_t tid) { timer_expired(tid); };
|
||||||
timers->get(t311)->set(this, 1000);
|
t310.set(1000, timer_expire_func);
|
||||||
|
t311.set(1000, timer_expire_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -3030,11 +3023,10 @@ void rrc::rrc_meas::generate_report(uint32_t meas_id)
|
||||||
report->meas_result_neigh_cells_present = neigh_list.size() > 0;
|
report->meas_result_neigh_cells_present = neigh_list.size() > 0;
|
||||||
|
|
||||||
m->nof_reports_sent++;
|
m->nof_reports_sent++;
|
||||||
timers->get(m->periodic_timer)->stop();
|
m->periodic_timer.stop();
|
||||||
|
|
||||||
if (m->nof_reports_sent < cfg->amount) {
|
if (m->nof_reports_sent < cfg->amount) {
|
||||||
timers->get(m->periodic_timer)->reset();
|
m->periodic_timer.run();
|
||||||
timers->get(m->periodic_timer)->run();
|
|
||||||
} else {
|
} else {
|
||||||
if (cfg->trigger_type == report_cfg_t::PERIODIC) {
|
if (cfg->trigger_type == report_cfg_t::PERIODIC) {
|
||||||
m->triggered = false;
|
m->triggered = false;
|
||||||
|
@ -3063,11 +3055,11 @@ bool rrc::rrc_meas::process_event(eutra_event_s* event, uint32_t tti, bool enter
|
||||||
} else if (exit_condition) {
|
} else if (exit_condition) {
|
||||||
if (!cell->timer_exit_triggered) {
|
if (!cell->timer_exit_triggered) {
|
||||||
cell->timer_exit_triggered = true;
|
cell->timer_exit_triggered = true;
|
||||||
cell->exit_tti = tti;
|
cell->exit_tti = tti;
|
||||||
} else if (srslte_tti_interval(tti, cell->exit_tti) >= event->time_to_trigger) {
|
} else if (srslte_tti_interval(tti, cell->exit_tti) >= event->time_to_trigger) {
|
||||||
m->triggered = false;
|
m->triggered = false;
|
||||||
cell->triggered = false;
|
cell->triggered = false;
|
||||||
timers->get(m->periodic_timer)->stop();
|
m->periodic_timer.stop();
|
||||||
if (event) {
|
if (event) {
|
||||||
if (event->event_id.type() == eutra_event_s::event_id_c_::types::event_a3 &&
|
if (event->event_id.type() == eutra_event_s::event_id_c_::types::event_a3 &&
|
||||||
event->event_id.event_a3().report_on_leave) {
|
event->event_id.event_a3().report_on_leave) {
|
||||||
|
@ -3232,9 +3224,10 @@ void rrc::rrc_meas::ho_finish() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5.5.4.1 expiry of periodical reporting timer
|
// 5.5.4.1 expiry of periodical reporting timer
|
||||||
bool rrc::rrc_meas::timer_expired(uint32_t timer_id) {
|
bool rrc::rrc_meas::timer_expired(uint32_t timer_id)
|
||||||
|
{
|
||||||
for (std::map<uint32_t, meas_t>::iterator iter = active.begin(); iter != active.end(); ++iter) {
|
for (std::map<uint32_t, meas_t>::iterator iter = active.begin(); iter != active.end(); ++iter) {
|
||||||
if (iter->second.periodic_timer == timer_id) {
|
if (iter->second.periodic_timer.id() == timer_id) {
|
||||||
log_h->info("Generate report MeasId=%d, from timerId=%d\n", iter->first, timer_id);
|
log_h->info("Generate report MeasId=%d, from timerId=%d\n", iter->first, timer_id);
|
||||||
generate_report(iter->first);
|
generate_report(iter->first);
|
||||||
return true;
|
return true;
|
||||||
|
@ -3245,11 +3238,12 @@ bool rrc::rrc_meas::timer_expired(uint32_t timer_id) {
|
||||||
|
|
||||||
void rrc::rrc_meas::stop_reports(meas_t* m)
|
void rrc::rrc_meas::stop_reports(meas_t* m)
|
||||||
{
|
{
|
||||||
timers->get(m->periodic_timer)->stop();
|
m->periodic_timer.stop();
|
||||||
m->triggered = false;
|
m->triggered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rrc::rrc_meas::stop_reports_object(uint32_t object_id) {
|
void rrc::rrc_meas::stop_reports_object(uint32_t object_id)
|
||||||
|
{
|
||||||
for (std::map<uint32_t, meas_t>::iterator iter = active.begin(); iter != active.end(); ++iter) {
|
for (std::map<uint32_t, meas_t>::iterator iter = active.begin(); iter != active.end(); ++iter) {
|
||||||
if (iter->second.object_id == object_id) {
|
if (iter->second.object_id == object_id) {
|
||||||
stop_reports(&iter->second);
|
stop_reports(&iter->second);
|
||||||
|
@ -3282,8 +3276,6 @@ void rrc::rrc_meas::remove_meas_report(uint32_t report_id) {
|
||||||
void rrc::rrc_meas::remove_meas_id(uint32_t measId)
|
void rrc::rrc_meas::remove_meas_id(uint32_t measId)
|
||||||
{
|
{
|
||||||
if (active.count(measId)) {
|
if (active.count(measId)) {
|
||||||
timers->get(active[measId].periodic_timer)->stop();
|
|
||||||
timers->release_id(active[measId].periodic_timer);
|
|
||||||
log_h->info("MEAS: Removed measId=%d\n", measId);
|
log_h->info("MEAS: Removed measId=%d\n", measId);
|
||||||
active.erase(measId);
|
active.erase(measId);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3293,8 +3285,6 @@ void rrc::rrc_meas::remove_meas_id(uint32_t measId)
|
||||||
|
|
||||||
void rrc::rrc_meas::remove_meas_id(std::map<uint32_t, meas_t>::iterator it)
|
void rrc::rrc_meas::remove_meas_id(std::map<uint32_t, meas_t>::iterator it)
|
||||||
{
|
{
|
||||||
timers->get(it->second.periodic_timer)->stop();
|
|
||||||
timers->release_id(it->second.periodic_timer);
|
|
||||||
log_h->info("MEAS: Removed measId=%d\n", it->first);
|
log_h->info("MEAS: Removed measId=%d\n", it->first);
|
||||||
active.erase(it);
|
active.erase(it);
|
||||||
}
|
}
|
||||||
|
@ -3443,16 +3433,20 @@ bool rrc::rrc_meas::parse_meas_config(meas_cfg_s* cfg)
|
||||||
// Stop the timer if the entry exists or create the timer if not
|
// Stop the timer if the entry exists or create the timer if not
|
||||||
bool is_new = false;
|
bool is_new = false;
|
||||||
if (active.count(meas_id->meas_id)) {
|
if (active.count(meas_id->meas_id)) {
|
||||||
timers->get(active[meas_id->meas_id].periodic_timer)->stop();
|
active[meas_id->meas_id].periodic_timer.stop();
|
||||||
} else {
|
} else {
|
||||||
is_new = true;
|
is_new = true;
|
||||||
active[meas_id->meas_id].periodic_timer = timers->get_unique_id();
|
active[meas_id->meas_id].periodic_timer = timers->get_unique_timer();
|
||||||
}
|
}
|
||||||
active[meas_id->meas_id].object_id = meas_id->meas_obj_id;
|
active[meas_id->meas_id].object_id = meas_id->meas_obj_id;
|
||||||
active[meas_id->meas_id].report_id = meas_id->report_cfg_id;
|
active[meas_id->meas_id].report_id = meas_id->report_cfg_id;
|
||||||
log_h->info("MEAS: %s measId=%d, measObjectId=%d, reportConfigId=%d, timer_id=%u, nof_values=%zd\n",
|
log_h->info("MEAS: %s measId=%d, measObjectId=%d, reportConfigId=%d, timer_id=%u, nof_values=%zd\n",
|
||||||
is_new ? "Added" : "Updated", meas_id->meas_id, meas_id->meas_obj_id, meas_id->report_cfg_id,
|
is_new ? "Added" : "Updated",
|
||||||
active[meas_id->meas_id].periodic_timer, active[meas_id->meas_id].cell_values.size());
|
meas_id->meas_id,
|
||||||
|
meas_id->meas_obj_id,
|
||||||
|
meas_id->report_cfg_id,
|
||||||
|
active[meas_id->meas_id].periodic_timer.id(),
|
||||||
|
active[meas_id->meas_id].cell_values.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -562,7 +562,7 @@ proc_outcome_t rrc::connection_request_proc::init(srslte::establishment_cause_t
|
||||||
return proc_outcome_t::error;
|
return proc_outcome_t::error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rrc_ptr->timers->get(rrc_ptr->t302)->is_running()) {
|
if (rrc_ptr->t302.is_running()) {
|
||||||
Info("Requested RRC connection establishment while T302 is running\n");
|
Info("Requested RRC connection establishment while T302 is running\n");
|
||||||
rrc_ptr->nas->set_barring(nas_interface_rrc::BARRING_MO_DATA);
|
rrc_ptr->nas->set_barring(nas_interface_rrc::BARRING_MO_DATA);
|
||||||
return proc_outcome_t::error;
|
return proc_outcome_t::error;
|
||||||
|
@ -600,8 +600,7 @@ proc_outcome_t rrc::connection_request_proc::step()
|
||||||
return proc_outcome_t::error;
|
return proc_outcome_t::error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rrc_ptr->timers->get(rrc_ptr->t300)->reset();
|
rrc_ptr->t300.run();
|
||||||
rrc_ptr->timers->get(rrc_ptr->t300)->run();
|
|
||||||
|
|
||||||
// Send connectionRequest message to lower layers
|
// Send connectionRequest message to lower layers
|
||||||
rrc_ptr->send_con_request(cause);
|
rrc_ptr->send_con_request(cause);
|
||||||
|
@ -618,14 +617,14 @@ proc_outcome_t rrc::connection_request_proc::step()
|
||||||
|
|
||||||
} else if (state == state_t::wait_t300) {
|
} else if (state == state_t::wait_t300) {
|
||||||
// Wait until t300 stops due to RRCConnectionSetup/Reject or expiry
|
// Wait until t300 stops due to RRCConnectionSetup/Reject or expiry
|
||||||
if (rrc_ptr->timers->get(rrc_ptr->t300)->is_running()) {
|
if (rrc_ptr->t300.is_running()) {
|
||||||
return proc_outcome_t::yield;
|
return proc_outcome_t::yield;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rrc_ptr->state == RRC_STATE_CONNECTED) {
|
if (rrc_ptr->state == RRC_STATE_CONNECTED) {
|
||||||
// Received ConnectionSetup
|
// Received ConnectionSetup
|
||||||
return proc_outcome_t::success;
|
return proc_outcome_t::success;
|
||||||
} else if (rrc_ptr->timers->get(rrc_ptr->t300)->is_expired()) {
|
} else if (rrc_ptr->t300.is_expired()) {
|
||||||
// T300 is expired: 5.3.3.6
|
// T300 is expired: 5.3.3.6
|
||||||
Warning("Timer T300 expired: ConnectionRequest timed out\n");
|
Warning("Timer T300 expired: ConnectionRequest timed out\n");
|
||||||
rrc_ptr->mac->reset();
|
rrc_ptr->mac->reset();
|
||||||
|
|
|
@ -68,8 +68,7 @@ void nas::plmn_search_proc::then(const srslte::proc_state_t& result)
|
||||||
|
|
||||||
// start T3411
|
// start T3411
|
||||||
nas_ptr->nas_log->debug("Starting T3411\n");
|
nas_ptr->nas_log->debug("Starting T3411\n");
|
||||||
nas_ptr->timers->get(nas_ptr->t3411)->reset();
|
nas_ptr->t3411.run();
|
||||||
nas_ptr->timers->get(nas_ptr->t3411)->run();
|
|
||||||
|
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
nas_ptr->enter_emm_deregistered();
|
nas_ptr->enter_emm_deregistered();
|
||||||
|
@ -225,12 +224,14 @@ proc_outcome_t nas::rrc_connect_proc::react(nas::rrc_connect_proc::connection_re
|
||||||
* NAS
|
* NAS
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
nas::nas(srslte::log* log_, srslte::timers* timers_) :
|
nas::nas(srslte::log* log_, srslte::timer_handler* timers_) :
|
||||||
nas_log(log_),
|
nas_log(log_),
|
||||||
pool(byte_buffer_pool::get_instance()),
|
pool(byte_buffer_pool::get_instance()),
|
||||||
plmn_searcher(this),
|
plmn_searcher(this),
|
||||||
rrc_connector(this),
|
rrc_connector(this),
|
||||||
timers(timers_)
|
timers(timers_),
|
||||||
|
t3410(timers_->get_unique_timer()),
|
||||||
|
t3411(timers_->get_unique_timer())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,10 +285,8 @@ void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure T3410 and T3411
|
// Configure T3410 and T3411
|
||||||
t3410 = timers->get_unique_id();
|
t3410.set(t3410_duration_ms, [this](uint32_t tid) { timer_expired(tid); });
|
||||||
timers->get(t3410)->set(this, t3410_duration_ms);
|
t3411.set(t3411_duration_ms, [this](uint32_t tid) { timer_expired(tid); });
|
||||||
t3411 = timers->get_unique_id();
|
|
||||||
timers->get(t3411)->set(this, t3411_duration_ms);
|
|
||||||
|
|
||||||
running = true;
|
running = true;
|
||||||
}
|
}
|
||||||
|
@ -318,11 +317,10 @@ void nas::run_tti(uint32_t tti)
|
||||||
|
|
||||||
void nas::timer_expired(uint32_t timeout_id)
|
void nas::timer_expired(uint32_t timeout_id)
|
||||||
{
|
{
|
||||||
if (timeout_id == t3410) {
|
if (timeout_id == t3410.id()) {
|
||||||
nas_log->info("Timer T3410 expired: starting T3411\n");
|
nas_log->info("Timer T3410 expired: starting T3411\n");
|
||||||
timers->get(t3411)->reset();
|
t3411.run();
|
||||||
timers->get(t3411)->run();
|
} else if (timeout_id == t3411.id()) {
|
||||||
} else if (timeout_id == t3411) {
|
|
||||||
nas_log->info("Timer T3411 expired: trying to attach again\n");
|
nas_log->info("Timer T3411 expired: trying to attach again\n");
|
||||||
start_attach_request(nullptr, srslte::establishment_cause_t::mo_sig);
|
start_attach_request(nullptr, srslte::establishment_cause_t::mo_sig);
|
||||||
} else {
|
} else {
|
||||||
|
@ -346,12 +344,11 @@ void nas::start_attach_request(srslte::proc_state_t* result, srslte::establishme
|
||||||
|
|
||||||
// start T3410
|
// start T3410
|
||||||
nas_log->debug("Starting T3410\n");
|
nas_log->debug("Starting T3410\n");
|
||||||
timers->get(t3410)->reset();
|
t3410.run();
|
||||||
timers->get(t3410)->run();
|
|
||||||
|
|
||||||
// stop T3411
|
// stop T3411
|
||||||
if (timers->get(t3411)->is_running()) {
|
if (t3411.is_running()) {
|
||||||
timers->get(t3411)->stop();
|
t3411.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: stop T3402
|
// Todo: stop T3402
|
||||||
|
@ -870,8 +867,8 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu)
|
||||||
nas_log->info("Received Attach Accept\n");
|
nas_log->info("Received Attach Accept\n");
|
||||||
|
|
||||||
// stop T3410
|
// stop T3410
|
||||||
if (timers->get(t3410)->is_running()) {
|
if (t3410.is_running()) {
|
||||||
timers->get(t3410)->stop();
|
t3410.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept = {};
|
LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept = {};
|
||||||
|
@ -1099,8 +1096,8 @@ void nas::parse_attach_reject(uint32_t lcid, unique_byte_buffer_t pdu)
|
||||||
nas_log->console("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause);
|
nas_log->console("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause);
|
||||||
|
|
||||||
// stop T3410
|
// stop T3410
|
||||||
if (timers->get(t3410)->is_running()) {
|
if (t3410.is_running()) {
|
||||||
timers->get(t3410)->stop();
|
t3410.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
enter_emm_deregistered();
|
enter_emm_deregistered();
|
||||||
|
@ -1599,9 +1596,9 @@ void nas::gen_attach_request(byte_buffer_t* msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop T3411
|
// stop T3411
|
||||||
if (timers->get(t3411)->is_running()) {
|
if (t3411.is_running()) {
|
||||||
nas_log->debug("Stopping T3411\n");
|
nas_log->debug("Stopping T3411\n");
|
||||||
timers->get(t3411)->stop();
|
t3411.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -369,9 +369,9 @@ int mac_unpack_test()
|
||||||
0xc3, 0xb3, 0x5c, 0xa3, 0x23, 0xad, 0x00, 0x03, 0x20, 0x1b, 0x00, 0x00, 0x00,
|
0xc3, 0xb3, 0x5c, 0xa3, 0x23, 0xad, 0x00, 0x03, 0x20, 0x1b, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0x89, 0x00, 0x00};
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0x89, 0x00, 0x00};
|
||||||
|
|
||||||
srslte::log_filter rlc_log("RLC");
|
srslte::log_filter rlc_log("RLC");
|
||||||
srslte::log_filter mac_log("MAC");
|
srslte::log_filter mac_log("MAC");
|
||||||
srslte::timers timers(64);
|
srslte::timer_handler timers(64);
|
||||||
|
|
||||||
mac_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
mac_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
mac_log.set_hex_limit(100000);
|
mac_log.set_hex_limit(100000);
|
||||||
|
@ -435,7 +435,7 @@ int mac_ul_sch_pdu_test1()
|
||||||
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
rlc_log.set_hex_limit(100000);
|
rlc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(64);
|
srslte::timer_handler timers(64);
|
||||||
|
|
||||||
// dummy layers
|
// dummy layers
|
||||||
phy_dummy phy;
|
phy_dummy phy;
|
||||||
|
@ -505,7 +505,7 @@ int mac_ul_logical_channel_prioritization_test1()
|
||||||
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
rlc_log.set_hex_limit(100000);
|
rlc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(64);
|
srslte::timer_handler timers(64);
|
||||||
|
|
||||||
// dummy layers
|
// dummy layers
|
||||||
phy_dummy phy;
|
phy_dummy phy;
|
||||||
|
@ -620,7 +620,7 @@ int mac_ul_logical_channel_prioritization_test2()
|
||||||
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
rlc_log.set_hex_limit(100000);
|
rlc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(64);
|
srslte::timer_handler timers(64);
|
||||||
|
|
||||||
// dummy layers
|
// dummy layers
|
||||||
phy_dummy phy;
|
phy_dummy phy;
|
||||||
|
@ -722,7 +722,7 @@ int mac_ul_logical_channel_prioritization_test3()
|
||||||
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
rlc_log.set_hex_limit(100000);
|
rlc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(64);
|
srslte::timer_handler timers(64);
|
||||||
|
|
||||||
// dummy layers
|
// dummy layers
|
||||||
phy_dummy phy;
|
phy_dummy phy;
|
||||||
|
@ -812,7 +812,7 @@ int mac_ul_sch_pdu_with_short_bsr_test()
|
||||||
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
rlc_log.set_hex_limit(100000);
|
rlc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(64);
|
srslte::timer_handler timers(64);
|
||||||
|
|
||||||
// dummy layers
|
// dummy layers
|
||||||
phy_dummy phy;
|
phy_dummy phy;
|
||||||
|
@ -900,7 +900,7 @@ int mac_ul_sch_pdu_with_padding_bsr_test()
|
||||||
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
rlc_log.set_hex_limit(100000);
|
rlc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(64);
|
srslte::timer_handler timers(64);
|
||||||
|
|
||||||
// dummy layers
|
// dummy layers
|
||||||
phy_dummy phy;
|
phy_dummy phy;
|
||||||
|
@ -997,7 +997,7 @@ int mac_ul_sch_pdu_one_byte_test()
|
||||||
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
rlc_log.set_hex_limit(100000);
|
rlc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(64);
|
srslte::timer_handler timers(64);
|
||||||
|
|
||||||
// dummy layers
|
// dummy layers
|
||||||
phy_dummy phy;
|
phy_dummy phy;
|
||||||
|
@ -1059,7 +1059,7 @@ int mac_ul_sch_pdu_two_byte_test()
|
||||||
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
rlc_log.set_hex_limit(100000);
|
rlc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(64);
|
srslte::timer_handler timers(64);
|
||||||
|
|
||||||
// dummy layers
|
// dummy layers
|
||||||
phy_dummy phy;
|
phy_dummy phy;
|
||||||
|
@ -1121,7 +1121,7 @@ int mac_ul_sch_pdu_three_byte_test()
|
||||||
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
rlc_log.set_hex_limit(100000);
|
rlc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(64);
|
srslte::timer_handler timers(64);
|
||||||
|
|
||||||
// dummy layers
|
// dummy layers
|
||||||
phy_dummy phy;
|
phy_dummy phy;
|
||||||
|
@ -1188,7 +1188,7 @@ struct ra_test {
|
||||||
|
|
||||||
struct ra_test test;
|
struct ra_test test;
|
||||||
|
|
||||||
int run_mac_ra_test(struct ra_test test, mac* mac, phy_dummy* phy, uint32_t* tti_state, srslte::timers* timers)
|
int run_mac_ra_test(struct ra_test test, mac* mac, phy_dummy* phy, uint32_t* tti_state, srslte::timer_handler* timers)
|
||||||
{
|
{
|
||||||
uint32_t tti = *tti_state;
|
uint32_t tti = *tti_state;
|
||||||
|
|
||||||
|
@ -1365,7 +1365,7 @@ int mac_random_access_test()
|
||||||
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
rlc_log.set_hex_limit(100000);
|
rlc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(64);
|
srslte::timer_handler timers(64);
|
||||||
|
|
||||||
// dummy layers
|
// dummy layers
|
||||||
phy_dummy phy;
|
phy_dummy phy;
|
||||||
|
|
|
@ -765,12 +765,6 @@ public:
|
||||||
ue->new_tb(dl_grant, (const uint8_t*)pdu->msg);
|
ue->new_tb(dl_grant, (const uint8_t*)pdu->msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
srslte::timers::timer* timer_get(uint32_t timer_id) { return timers.get(timer_id); }
|
|
||||||
|
|
||||||
uint32_t timer_get_unique_id() { return timers.get_unique_id(); }
|
|
||||||
|
|
||||||
void timer_release_id(uint32_t timer_id) { timers.release_id(timer_id); }
|
|
||||||
|
|
||||||
void step_timer() { timers.step_all(); }
|
void step_timer() { timers.step_all(); }
|
||||||
|
|
||||||
void add_srb(uint32_t lcid, pdcp_config_t pdcp_config)
|
void add_srb(uint32_t lcid, pdcp_config_t pdcp_config)
|
||||||
|
@ -918,7 +912,7 @@ private:
|
||||||
uint32_t prach_preamble_index = 0;
|
uint32_t prach_preamble_index = 0;
|
||||||
uint16_t dl_rnti = 0;
|
uint16_t dl_rnti = 0;
|
||||||
uint16_t crnti = TTCN3_CRNTI;
|
uint16_t crnti = TTCN3_CRNTI;
|
||||||
srslte::timers timers;
|
srslte::timer_handler timers;
|
||||||
bool last_dl_ndi[2 * FDD_HARQ_DELAY_MS] = {};
|
bool last_dl_ndi[2 * FDD_HARQ_DELAY_MS] = {};
|
||||||
bool last_ul_ndi[2 * FDD_HARQ_DELAY_MS] = {};
|
bool last_ul_ndi[2 * FDD_HARQ_DELAY_MS] = {};
|
||||||
|
|
||||||
|
|
|
@ -206,17 +206,17 @@ int security_command_test()
|
||||||
nas_log.set_hex_limit(100000);
|
nas_log.set_hex_limit(100000);
|
||||||
rrc_log.set_hex_limit(100000);
|
rrc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(10);
|
srslte::timer_handler timers(10);
|
||||||
|
|
||||||
rrc_dummy rrc_dummy;
|
rrc_dummy rrc_dummy;
|
||||||
gw_dummy gw;
|
gw_dummy gw;
|
||||||
|
|
||||||
usim_args_t args;
|
usim_args_t args;
|
||||||
args.algo = "xor";
|
args.algo = "xor";
|
||||||
args.imei = "353490069873319";
|
args.imei = "353490069873319";
|
||||||
args.imsi = "001010123456789";
|
args.imsi = "001010123456789";
|
||||||
args.k = "00112233445566778899aabbccddeeff";
|
args.k = "00112233445566778899aabbccddeeff";
|
||||||
args.op = "63BFA50EE6523365FF14C1F45F88737D";
|
args.op = "63BFA50EE6523365FF14C1F45F88737D";
|
||||||
args.using_op = true;
|
args.using_op = true;
|
||||||
|
|
||||||
// init USIM
|
// init USIM
|
||||||
|
@ -278,9 +278,9 @@ int mme_attach_request_test()
|
||||||
usim_log.set_hex_limit(100000);
|
usim_log.set_hex_limit(100000);
|
||||||
gw_log.set_hex_limit(100000);
|
gw_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(10);
|
srslte::timer_handler timers(10);
|
||||||
|
|
||||||
rrc_dummy rrc_dummy;
|
rrc_dummy rrc_dummy;
|
||||||
pdcp_dummy pdcp_dummy;
|
pdcp_dummy pdcp_dummy;
|
||||||
|
|
||||||
srsue::usim usim(&usim_log);
|
srsue::usim usim(&usim_log);
|
||||||
|
@ -358,10 +358,10 @@ int esm_info_request_test()
|
||||||
nas_log.set_hex_limit(100000);
|
nas_log.set_hex_limit(100000);
|
||||||
rrc_log.set_hex_limit(100000);
|
rrc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(10);
|
srslte::timer_handler timers(10);
|
||||||
|
|
||||||
rrc_dummy rrc_dummy;
|
rrc_dummy rrc_dummy;
|
||||||
gw_dummy gw;
|
gw_dummy gw;
|
||||||
|
|
||||||
usim_args_t args;
|
usim_args_t args;
|
||||||
args.algo = "xor";
|
args.algo = "xor";
|
||||||
|
@ -417,7 +417,7 @@ int dedicated_eps_bearer_test()
|
||||||
nas_log.set_hex_limit(100000);
|
nas_log.set_hex_limit(100000);
|
||||||
rrc_log.set_hex_limit(100000);
|
rrc_log.set_hex_limit(100000);
|
||||||
|
|
||||||
srslte::timers timers(10);
|
srslte::timer_handler timers(10);
|
||||||
|
|
||||||
rrc_dummy rrc_dummy;
|
rrc_dummy rrc_dummy;
|
||||||
gw_dummy gw;
|
gw_dummy gw;
|
||||||
|
|
Loading…
Reference in New Issue