|
|
|
@ -44,16 +44,13 @@
|
|
|
|
|
namespace srsue {
|
|
|
|
|
|
|
|
|
|
template <std::size_t N, typename Tgrant, typename Taction, typename Tphygrant>
|
|
|
|
|
class ul_harq_entity
|
|
|
|
|
{
|
|
|
|
|
class ul_harq_entity {
|
|
|
|
|
public:
|
|
|
|
|
static uint32_t pidof(uint32_t tti)
|
|
|
|
|
{
|
|
|
|
|
return (uint32_t) tti%N;
|
|
|
|
|
static uint32_t pidof(uint32_t tti) {
|
|
|
|
|
return (uint32_t) tti % N;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ul_harq_entity() : proc(N)
|
|
|
|
|
{
|
|
|
|
|
ul_harq_entity() : proc(N) {
|
|
|
|
|
contention_timer = NULL;
|
|
|
|
|
|
|
|
|
|
pcap = NULL;
|
|
|
|
@ -68,15 +65,14 @@ public:
|
|
|
|
|
bool init(srslte::log *log_h_,
|
|
|
|
|
mac_interface_rrc_common::ue_rnti_t *rntis_,
|
|
|
|
|
mac_interface_rrc_common::ul_harq_params_t *params_,
|
|
|
|
|
srslte::timers::timer* contention_timer_,
|
|
|
|
|
mux *mux_unit_)
|
|
|
|
|
{
|
|
|
|
|
srslte::timers::timer *contention_timer_,
|
|
|
|
|
mux *mux_unit_) {
|
|
|
|
|
log_h = log_h_;
|
|
|
|
|
mux_unit = mux_unit_;
|
|
|
|
|
params = params_;
|
|
|
|
|
rntis = rntis_;
|
|
|
|
|
contention_timer = contention_timer_;
|
|
|
|
|
for (uint32_t i=0;i<N;i++) {
|
|
|
|
|
for (uint32_t i = 0; i < N; i++) {
|
|
|
|
|
if (!proc[i].init(i, this)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@ -84,29 +80,29 @@ public:
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void reset()
|
|
|
|
|
{
|
|
|
|
|
for (uint32_t i=0;i<N;i++) {
|
|
|
|
|
void reset() {
|
|
|
|
|
for (uint32_t i = 0; i < N; i++) {
|
|
|
|
|
proc[i].reset();
|
|
|
|
|
}
|
|
|
|
|
ul_sps_assig.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void reset_ndi()
|
|
|
|
|
{
|
|
|
|
|
for (uint32_t i=0;i<N;i++) {
|
|
|
|
|
void reset_ndi() {
|
|
|
|
|
for (uint32_t i = 0; i < N; i++) {
|
|
|
|
|
proc[i].reset_ndi();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void start_pcap(srslte::mac_pcap* pcap_)
|
|
|
|
|
{
|
|
|
|
|
void start_pcap(srslte::mac_pcap *pcap_) {
|
|
|
|
|
pcap = pcap_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***************** PHY->MAC interface for UL processes **************************/
|
|
|
|
|
void new_grant_ul(Tgrant grant, Taction *action)
|
|
|
|
|
void new_grant_ul(Tgrant grant, Taction *action) {
|
|
|
|
|
new_grant_ul_ack(grant, NULL, action);
|
|
|
|
|
}
|
|
|
|
|
void new_grant_ul_ack(Tgrant grant, bool *ack, Taction *action)
|
|
|
|
|
{
|
|
|
|
|
if (grant.rnti_type == SRSLTE_RNTI_USER ||
|
|
|
|
|
grant.rnti_type == SRSLTE_RNTI_TEMP ||
|
|
|
|
@ -115,27 +111,20 @@ public:
|
|
|
|
|
if (grant.rnti_type == SRSLTE_RNTI_USER && proc[pidof(grant.tti)].is_sps()) {
|
|
|
|
|
grant.ndi[0] = true;
|
|
|
|
|
}
|
|
|
|
|
run_tti(grant.tti, &grant, action);
|
|
|
|
|
run_tti(grant.tti, &grant, ack, action);
|
|
|
|
|
} else if (grant.rnti_type == SRSLTE_RNTI_SPS) {
|
|
|
|
|
if (grant.ndi[0]) {
|
|
|
|
|
grant.ndi[0] = proc[pidof(grant.tti)].get_ndi();
|
|
|
|
|
run_tti(grant.tti, &grant, action);
|
|
|
|
|
run_tti(grant.tti, &grant, ack, action);
|
|
|
|
|
} else {
|
|
|
|
|
Info("Not implemented\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void new_grant_ul_ack(Tgrant grant, bool ack, Taction *action)
|
|
|
|
|
{
|
|
|
|
|
set_ack(grant.tti, ack, action);
|
|
|
|
|
new_grant_ul(grant, action);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void harq_recv(uint32_t tti, bool ack, Taction *action)
|
|
|
|
|
{
|
|
|
|
|
set_ack(tti, ack, action);
|
|
|
|
|
run_tti(tti, NULL, action);
|
|
|
|
|
run_tti(tti, NULL, &ack, action);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int get_current_tbs(uint32_t tti)
|
|
|
|
@ -206,10 +195,19 @@ private:
|
|
|
|
|
bzero(&cur_grant, sizeof(Tgrant));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void reset_ndi() { ndi = false; }
|
|
|
|
|
void reset_ndi() { cur_grant.ndi[0] = false; }
|
|
|
|
|
|
|
|
|
|
void run_tti(uint32_t tti_tx, Tgrant *grant, Taction* action)
|
|
|
|
|
void run_tti(uint32_t tti_tx, Tgrant *grant, bool *ack, Taction* action)
|
|
|
|
|
{
|
|
|
|
|
if (ack) {
|
|
|
|
|
if (grant) {
|
|
|
|
|
if (grant->ndi[0] == get_ndi()) {
|
|
|
|
|
*ack = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
set_harq_feedback(*ack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t max_retx;
|
|
|
|
|
if (is_msg3) {
|
|
|
|
|
max_retx = harq_entity->params->max_harq_msg3_tx;
|
|
|
|
@ -219,7 +217,7 @@ private:
|
|
|
|
|
|
|
|
|
|
// Receive and route HARQ feedbacks
|
|
|
|
|
if (grant) {
|
|
|
|
|
if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi[0] != get_ndi() && grant->phy_grant.ul.mcs.idx < 29) ||
|
|
|
|
|
if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi[0] != get_ndi()) ||
|
|
|
|
|
(grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) ||
|
|
|
|
|
grant->is_from_rar)
|
|
|
|
|
{
|
|
|
|
@ -255,7 +253,7 @@ private:
|
|
|
|
|
generate_retx(tti_tx, grant, action);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
Warning("UL %d: Received mcs=%d but no previous grant available for this PID.\n", pid, grant->phy_grant.ul.mcs.idx);
|
|
|
|
|
Warning("UL %d: Received retransmission but no previous grant available for this PID.\n", pid);
|
|
|
|
|
}
|
|
|
|
|
} else if (has_grant()) {
|
|
|
|
|
// Non-Adaptive Re-Tx
|
|
|
|
@ -294,7 +292,7 @@ private:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool has_grant() { return is_grant_configured; }
|
|
|
|
|
bool get_ndi() { return ndi; }
|
|
|
|
|
bool get_ndi() { return cur_grant.ndi[0]; }
|
|
|
|
|
bool is_sps() { return false; }
|
|
|
|
|
uint32_t last_tx_tti() { return tti_last_tx; }
|
|
|
|
|
uint32_t get_nof_retx() { return current_tx_nb; }
|
|
|
|
@ -307,7 +305,6 @@ private:
|
|
|
|
|
uint32_t current_tx_nb;
|
|
|
|
|
uint32_t current_irv;
|
|
|
|
|
bool harq_feedback;
|
|
|
|
|
bool ndi;
|
|
|
|
|
srslte::log *log_h;
|
|
|
|
|
ul_harq_entity *harq_entity;
|
|
|
|
|
bool is_grant_configured;
|
|
|
|
@ -398,22 +395,10 @@ private:
|
|
|
|
|
|
|
|
|
|
// Implements Section 5.4.2.1
|
|
|
|
|
// Called with UL grant
|
|
|
|
|
void run_tti(uint32_t tti, Tgrant *grant, Taction* action)
|
|
|
|
|
void run_tti(uint32_t tti, Tgrant *grant, bool *ack, Taction* action)
|
|
|
|
|
{
|
|
|
|
|
uint32_t tti_tx = (tti+action->tti_offset)%10240;
|
|
|
|
|
proc[pidof(tti_tx)].run_tti(tti_tx, grant, action);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void set_ack(uint32_t tti, bool ack, Taction *action)
|
|
|
|
|
{
|
|
|
|
|
int tti_harq = (int) tti - action->tti_offset;
|
|
|
|
|
if (tti_harq < 0) {
|
|
|
|
|
tti_harq += 10240;
|
|
|
|
|
}
|
|
|
|
|
uint32_t pid_harq = pidof(tti_harq);
|
|
|
|
|
if (proc[pid_harq].has_grant() && (proc[pid_harq].last_tx_tti() <= (uint32_t)tti_harq)) {
|
|
|
|
|
proc[pid_harq].set_harq_feedback(ack);
|
|
|
|
|
}
|
|
|
|
|
proc[pidof(tti_tx)].run_tti(tti_tx, grant, ack, action);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ul_sps ul_sps_assig;
|
|
|
|
|