From 058fbd71127a3fb1c38bd575c455beef2b42721f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 14 Nov 2017 11:48:19 +0100 Subject: [PATCH] Fix adaptive retx in UE --- lib/src/phy/ue/ue_ul.c | 2 +- srsue/hdr/mac/ul_harq.h | 119 +++++++++++++++-------------------- srsue/hdr/phy/phch_worker.h | 1 + srsue/src/mac/mac.cc | 2 +- srsue/src/mac/mux.cc | 7 +-- srsue/src/phy/phch_worker.cc | 48 +++++++------- 6 files changed, 84 insertions(+), 95 deletions(-) diff --git a/lib/src/phy/ue/ue_ul.c b/lib/src/phy/ue/ue_ul.c index 853937f7c..ec2809dfe 100644 --- a/lib/src/phy/ue/ue_ul.c +++ b/lib/src/phy/ue/ue_ul.c @@ -453,7 +453,7 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q, if (srslte_pusch_encode(&q->pusch, &q->pusch_cfg, softbuffer, data, uci_data, rnti, q->sf_symbols)) { fprintf(stderr, "Error encoding TB\n"); - return ret; + return SRSLTE_ERROR; } if (q->signals_pregenerated) { diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 50143a571..5b7426b35 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -44,39 +44,35 @@ namespace srsue { template -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; - mux_unit = NULL; - log_h = NULL; - params = NULL; - rntis = NULL; - average_retx = 0; - nof_pkts = 0; + pcap = NULL; + mux_unit = NULL; + log_h = NULL; + params = NULL; + rntis = NULL; + average_retx = 0; + nof_pkts = 0; } - bool init(srslte::log *log_h_, + 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_) - { - log_h = log_h_; - mux_unit = mux_unit_; - params = params_; - rntis = rntis_; + 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;iMAC 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 run_tti(uint32_t tti_tx, Tgrant *grant, Taction* action) + void reset_ndi() { cur_grant.ndi[0] = false; } + + 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,9 +217,9 @@ 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) || - (grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) || - grant->is_from_rar) + if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi[0] != get_ndi()) || + (grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) || + grant->is_from_rar) { // New transmission @@ -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,24 +395,12 @@ 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); + proc[pidof(tti_tx)].run_tti(tti_tx, grant, ack, 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); - } - } - ul_sps ul_sps_assig; srslte::timers::timer *contention_timer; diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index c26966c17..61a3b7f23 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -153,6 +153,7 @@ private: // Save last TBS for mcs>28 cases int last_dl_tbs[2*HARQ_DELAY_MS][SRSLTE_MAX_CODEWORDS]; int last_ul_tbs[2*HARQ_DELAY_MS]; + uint32_t last_ul_tti[2*HARQ_DELAY_MS]; srslte_mod_t last_ul_mod[2*HARQ_DELAY_MS]; // Metrics diff --git a/srsue/src/mac/mac.cc b/srsue/src/mac/mac.cc index f8d10bb34..3d1f60f56 100644 --- a/srsue/src/mac/mac.cc +++ b/srsue/src/mac/mac.cc @@ -308,7 +308,7 @@ void mac::new_grant_ul(mac_interface_phy::mac_grant_t grant, mac_interface_phy:: void mac::new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, bool ack, mac_interface_phy::tb_action_ul_t* action) { int tbs = ul_harq.get_current_tbs(tti); - ul_harq.new_grant_ul_ack(grant, ack, action); + ul_harq.new_grant_ul_ack(grant, &ack, action); if (!ack) { metrics.tx_errors++; } else { diff --git a/srsue/src/mac/mux.cc b/srsue/src/mac/mux.cc index 957c257a1..4e1a3b870 100644 --- a/srsue/src/mac/mux.cc +++ b/srsue/src/mac/mux.cc @@ -236,8 +236,7 @@ uint8_t* mux::pdu_get(uint8_t *payload, uint32_t pdu_sz, uint32_t tx_tti, uint32 // Now allocate the SDUs from the RLC for (uint32_t i=0;iinfo("Allocating scheduled lch=%d len=%d\n", lch[i].id, lch[i].sched_len); - allocate_sdu(lch[i].id, &pdu_msg, lch[i].sched_len); + allocate_sdu(lch[i].id, &pdu_msg, lch[i].sched_len); } } @@ -285,7 +284,7 @@ bool mux::sched_sdu(lchid_t *ch, int *sdu_space, int max_sdu_sz) sched_len = *sdu_space; } - log_h->info("SDU: scheduled lcid=%d, rlc_buffer=%d, allocated=%d/%d\n", + log_h->debug("SDU: scheduled lcid=%d, rlc_buffer=%d, allocated=%d/%d\n", ch->id, ch->buffer_len, sched_len, sdu_space?*sdu_space:0); *sdu_space -= sched_len; @@ -317,7 +316,7 @@ bool mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_sz) sdu_len = pdu_msg->get()->set_sdu(lcid, sdu_len, rlc); if (sdu_len > 0) { // new SDU could be added - Info("SDU: allocated lcid=%d, rlc_buffer=%d, allocated=%d/%d, max_sdu_sz=%d, remaining=%d\n", + Debug("SDU: allocated lcid=%d, rlc_buffer=%d, allocated=%d/%d, max_sdu_sz=%d, remaining=%d\n", lcid, buffer_state, sdu_len, sdu_space, max_sdu_sz, pdu_msg->rem_size()); return true; } else { diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index ff7412d77..ce35680d0 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -322,9 +322,9 @@ void phch_worker::work_imp() ul_action.tti_offset = HARQ_DELAY_MS; /* Send UL grant or HARQ information (from PHICH) to MAC */ - if (ul_grant_available && ul_ack_available && ul_mac_grant.phy_grant.ul.mcs.idx < 29) { + if (ul_grant_available && ul_ack_available) { phy->mac->new_grant_ul_ack(ul_mac_grant, ul_ack, &ul_action); - } else if (ul_grant_available && (!ul_ack_available || ul_mac_grant.phy_grant.ul.mcs.idx < 29)) { + } else if (ul_grant_available && !ul_ack_available) { phy->mac->new_grant_ul(ul_mac_grant, &ul_action); } else if (!ul_grant_available && ul_ack_available) { phy->mac->harq_recv(tti, ul_ack, &ul_action); @@ -743,30 +743,36 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) } } - if (ret) { + // Handle Format0 adaptive retx + if (ret) { // Use last TBS for this TB in case of mcs>28 if (grant->phy_grant.ul.mcs.idx > 28) { - grant->phy_grant.ul.mcs.tbs = last_ul_tbs[TTI_RX(tti)%(2*HARQ_DELAY_MS)]; - Info("RETX: mcs=%d, old_tbs=%d pid=%d\n", grant->phy_grant.ul.mcs.idx, grant->phy_grant.ul.mcs.tbs, TTI_TX(tti)%(2*HARQ_DELAY_MS)); + // Make sure we received a grant in the previous TTI for this PID + if (last_ul_tti[TTI_RX(tti)%(2*HARQ_DELAY_MS)] == TTI_RX(tti)) { + grant->phy_grant.ul.mcs.tbs = last_ul_tbs[TTI_RX(tti)%(2*HARQ_DELAY_MS)]; + grant->phy_grant.ul.mcs.mod = last_ul_mod[TTI_RX(tti)%(2*HARQ_DELAY_MS)]; + grant->phy_grant.ul.Qm = srslte_mod_bits_x_symbol(grant->phy_grant.ul.mcs.mod); + } else { + Warning("Missed original grant in adaptive retx\n"); + ret = false; + } } + } + if (ret) { last_ul_tbs[TTI_RX(tti)%(2*HARQ_DELAY_MS)] = grant->phy_grant.ul.mcs.tbs; - - if (grant->phy_grant.ul.mcs.mod == SRSLTE_MOD_LAST) { - grant->phy_grant.ul.mcs.mod = last_ul_mod[TTI_RX(tti)%(2*HARQ_DELAY_MS)]; - grant->phy_grant.ul.Qm = srslte_mod_bits_x_symbol(grant->phy_grant.ul.mcs.mod); - } last_ul_mod[TTI_RX(tti)%(2*HARQ_DELAY_MS)] = grant->phy_grant.ul.mcs.mod; - } + last_ul_tti[TTI_RX(tti)%(2*HARQ_DELAY_MS)] = TTI_TX(tti); - /* Limit UL modulation if not supported by the UE or disabled by higher layers */ - if (!phy->config->enable_64qam) { - if (grant->phy_grant.ul.mcs.mod >= SRSLTE_MOD_64QAM) { - grant->phy_grant.ul.mcs.mod = SRSLTE_MOD_16QAM; - grant->phy_grant.ul.Qm = 4; + /* Limit UL modulation if not supported by the UE or disabled by higher layers */ + if (!phy->config->enable_64qam) { + if (grant->phy_grant.ul.mcs.mod >= SRSLTE_MOD_64QAM) { + grant->phy_grant.ul.mcs.mod = SRSLTE_MOD_16QAM; + grant->phy_grant.ul.Qm = 4; + } } } - + /* Make sure the grant is valid */ if (ret && !srslte_dft_precoding_valid_prb(grant->phy_grant.ul.L_prb) && grant->phy_grant.ul.L_prb <= cell.nof_prb) { Warning("Received invalid UL grant. L=%d\n", grant->phy_grant.ul.L_prb); @@ -783,11 +789,9 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) if (SRSLTE_VERBOSE_ISINFO()) { srslte_ra_pusch_fprint(stdout, &dci_unpacked, cell.nof_prb); } - - return true; - } else { - return false; - } + } + + return ret; } void phch_worker::reset_uci()