mirror of https://github.com/PentHertz/srsLTE.git
Fix adaptive retx in UE
This commit is contained in:
parent
72d83be8bc
commit
058fbd7112
|
@ -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) {
|
||||
|
|
|
@ -44,39 +44,35 @@
|
|||
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;
|
||||
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;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 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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;i<lch.size();i++) {
|
||||
if (lch[i].sched_len != 0) {
|
||||
log_h->info("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 {
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue