mirror of https://github.com/pvnis/srsRAN_4G.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
4.3 KiB
C++
238 lines
4.3 KiB
C++
8 years ago
|
|
||
|
#include <string.h>
|
||
|
#include <boost/concept_check.hpp>
|
||
|
|
||
|
#include "srslte/srslte.h"
|
||
|
#include "srslte/common/pdu.h"
|
||
|
#include "mac/scheduler.h"
|
||
|
|
||
|
#define Error(fmt, ...) log_h->error_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||
|
#define Warning(fmt, ...) log_h->warning_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||
|
#define Info(fmt, ...) log_h->info_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||
|
#define Debug(fmt, ...) log_h->debug_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||
|
|
||
|
namespace srsenb {
|
||
|
|
||
|
/******************************************************
|
||
|
*
|
||
|
* These classes manage the HARQ Processes.
|
||
|
* There is a common class and two child classes for UL and DL.
|
||
|
*
|
||
|
******************************************************/
|
||
|
|
||
|
void harq_proc::config(uint32_t id_, uint32_t max_retx_, srslte::log* log_h_)
|
||
|
{
|
||
|
log_h = log_h_;
|
||
|
id = id_;
|
||
|
max_retx = max_retx_;
|
||
|
ndi = false;
|
||
|
}
|
||
|
|
||
|
void harq_proc::set_max_retx(uint32_t max_retx_) {
|
||
|
log_h->debug("Set max_retx=%d pid=%d\n", max_retx_, id);
|
||
|
max_retx = max_retx_;
|
||
|
}
|
||
|
|
||
|
uint32_t harq_proc::get_id()
|
||
|
{
|
||
|
return id;
|
||
|
}
|
||
|
|
||
|
void harq_proc::reset()
|
||
|
{
|
||
|
active = false;
|
||
|
ack = true;
|
||
|
ack_received = false;
|
||
|
n_rtx = 0;
|
||
|
tti = 0;
|
||
|
last_mcs = -1;
|
||
|
last_tbs = -1;
|
||
|
tx_cnt = 0;
|
||
|
}
|
||
|
|
||
|
bool harq_proc::is_empty()
|
||
|
{
|
||
|
return !active || (active && ack && ack_received);
|
||
|
}
|
||
|
|
||
|
bool harq_proc::has_pending_retx_common()
|
||
|
{
|
||
|
return !ack && n_rtx < max_retx;
|
||
|
}
|
||
|
|
||
|
uint32_t harq_proc::get_tti()
|
||
|
{
|
||
|
return tti;
|
||
|
}
|
||
|
|
||
|
bool harq_proc::get_ack()
|
||
|
{
|
||
|
return ack;
|
||
|
}
|
||
|
|
||
|
void harq_proc::set_ack(bool ack_)
|
||
|
{
|
||
|
ack = ack_;
|
||
|
ack_received = true;
|
||
|
log_h->debug("ACK=%d received pid=%d, n_rtx=%d, max_retx=%d\n", ack_, id, n_rtx, max_retx);
|
||
|
if (n_rtx >= max_retx) {
|
||
|
Warning("SCHED: discarting TB pid=%d, tti=%d, maximum number of retx exceeded (%d)\n", id, tti, max_retx);
|
||
|
active = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void harq_proc::new_tx_common(uint32_t tti_, int mcs, int tbs)
|
||
|
{
|
||
|
reset();
|
||
|
ndi = !ndi;
|
||
|
tti = tti_;
|
||
|
tx_cnt++;
|
||
|
last_mcs = mcs;
|
||
|
last_tbs = tbs;
|
||
|
|
||
|
if (max_retx) {
|
||
|
active = true;
|
||
|
} else {
|
||
|
active = false; // Can reuse this process if no retx are allowed
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void harq_proc::new_retx(uint32_t tti_, int *mcs, int *tbs)
|
||
|
{
|
||
|
ack_received = false;
|
||
|
tti = tti_;
|
||
|
n_rtx++;
|
||
|
if (mcs) {
|
||
|
*mcs = last_mcs;
|
||
|
}
|
||
|
if (tbs) {
|
||
|
*tbs = last_tbs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint32_t harq_proc::nof_tx()
|
||
|
{
|
||
|
return tx_cnt;
|
||
|
}
|
||
|
|
||
|
uint32_t harq_proc::nof_retx()
|
||
|
{
|
||
|
return n_rtx;
|
||
|
}
|
||
|
|
||
|
bool harq_proc::get_ndi()
|
||
|
{
|
||
|
return ndi;
|
||
|
}
|
||
|
|
||
|
/******************************************************
|
||
|
* UE::DL HARQ class *
|
||
|
******************************************************/
|
||
|
|
||
|
void dl_harq_proc::new_tx(uint32_t tti, int mcs, int tbs, uint32_t n_cce_)
|
||
|
{
|
||
|
n_cce = n_cce_;
|
||
|
new_tx_common(tti, mcs, tbs);
|
||
|
}
|
||
|
|
||
|
uint32_t dl_harq_proc::get_n_cce()
|
||
|
{
|
||
|
return n_cce;
|
||
|
}
|
||
|
|
||
|
uint32_t dl_harq_proc::get_rbgmask()
|
||
|
{
|
||
|
return rbgmask;
|
||
|
}
|
||
|
|
||
|
void dl_harq_proc::set_rbgmask(uint32_t new_mask)
|
||
|
{
|
||
|
rbgmask = new_mask;
|
||
|
}
|
||
|
|
||
|
bool dl_harq_proc::has_pending_retx(uint32_t current_tti)
|
||
|
{
|
||
|
return srslte_tti_interval(current_tti, tti) >= 8 && has_pending_retx_common();
|
||
|
}
|
||
|
|
||
|
int dl_harq_proc::get_tbs()
|
||
|
{
|
||
|
return last_tbs;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************************************
|
||
|
* UE::UL HARQ class *
|
||
|
******************************************************/
|
||
|
|
||
|
ul_harq_proc::ul_alloc_t ul_harq_proc::get_alloc()
|
||
|
{
|
||
|
return allocation;
|
||
|
}
|
||
|
|
||
|
void ul_harq_proc::set_alloc(ul_harq_proc::ul_alloc_t alloc)
|
||
|
{
|
||
|
is_adaptive = false;
|
||
|
memcpy(&allocation, &alloc, sizeof(ul_alloc_t));
|
||
|
}
|
||
|
|
||
|
void ul_harq_proc::same_alloc()
|
||
|
{
|
||
|
is_adaptive = true;
|
||
|
}
|
||
|
|
||
|
bool ul_harq_proc::is_adaptive_retx()
|
||
|
{
|
||
|
return is_adaptive;
|
||
|
}
|
||
|
|
||
|
void ul_harq_proc::new_tx(uint32_t tti_, int mcs, int tbs)
|
||
|
{
|
||
|
need_ack = true;
|
||
|
new_tx_common(tti_, mcs, tbs);
|
||
|
pending_data = tbs;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool ul_harq_proc::has_pending_ack()
|
||
|
{
|
||
|
bool ret = need_ack;
|
||
|
|
||
|
// Reset if already received a positive ACK
|
||
|
if (active && ack) {
|
||
|
active = false;
|
||
|
}
|
||
|
if (!active) {
|
||
|
pending_data = 0;
|
||
|
need_ack = false;
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
uint32_t ul_harq_proc::get_pending_data()
|
||
|
{
|
||
|
return pending_data;
|
||
|
}
|
||
|
|
||
|
void ul_harq_proc::set_rar_mcs(uint32_t mcs)
|
||
|
{
|
||
|
rar_mcs = mcs;
|
||
|
has_rar_mcs = true;
|
||
|
}
|
||
|
|
||
|
bool ul_harq_proc::get_rar_mcs(int *mcs)
|
||
|
{
|
||
|
if (has_rar_mcs) {
|
||
|
if (mcs) {
|
||
|
*mcs = (int) rar_mcs;
|
||
|
}
|
||
|
has_rar_mcs = false;
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
}
|