diff --git a/srslte/examples/pdsch_enodeb.c b/srslte/examples/pdsch_enodeb.c index c317d2a32..80a37211b 100644 --- a/srslte/examples/pdsch_enodeb.c +++ b/srslte/examples/pdsch_enodeb.c @@ -254,7 +254,7 @@ void base_init() { exit(-1); } - srslte_pdsch_set_rnti(&pdsch, 1234); + srslte_pdsch_set_rnti(&pdsch, 4660); if (srslte_softbuffer_tx_init(&softbuffer, cell)) { fprintf(stderr, "Error initiating soft buffer\n"); diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index 693181fd7..366c22aee 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -64,12 +64,18 @@ sem_t plot_sem; uint32_t plot_sf_idx=0; #endif +#define PLOT_CHEST_ARGUMENT +#define PRINT_CHANGE_SCHEDULIGN + /********************************************************************** * Program arguments processing ***********************************************************************/ typedef struct { int nof_subframes; bool disable_plots; + bool disable_plots_except_constellation; + bool disable_cfo; + uint32_t time_offset; int force_N_id_2; uint16_t rnti; char *input_file_name; @@ -87,10 +93,14 @@ typedef struct { }prog_args_t; void args_default(prog_args_t *args) { + args->disable_plots = false; + args->disable_plots_except_constellation = false; args->nof_subframes = -1; args->rnti = SRSLTE_SIRNTI; args->force_N_id_2 = -1; // Pick the best args->input_file_name = NULL; + args->disable_cfo = false; + args->time_offset = 0; args->file_nof_prb = 6; args->file_nof_ports = 1; args->file_cell_id = 0; @@ -105,7 +115,7 @@ void args_default(prog_args_t *args) { } void usage(prog_args_t *args, char *prog) { - printf("Usage: %s [agpPcildnruv] -f rx_frequency (in Hz) | -i input_file\n", prog); + printf("Usage: %s [agpPcildDnruv] -f rx_frequency (in Hz) | -i input_file\n", prog); #ifndef DISABLE_UHD printf("\t-a UHD args [Default %s]\n", args->uhd_args); printf("\t-g UHD fix RX gain [Default AGC]\n"); @@ -117,10 +127,13 @@ void usage(prog_args_t *args, char *prog) { printf("\t-p nof_prb for input file [Default %d]\n", args->file_nof_prb); printf("\t-P nof_ports for input file [Default %d]\n", args->file_nof_ports); printf("\t-c cell_id for input file [Default %d]\n", args->file_cell_id); - printf("\t-r RNTI [Default 0x%x]\n",args->rnti); + printf("\t-r RNTI in Hex [Default 0x%x]\n",args->rnti); printf("\t-l Force N_id_2 [Default best]\n"); + printf("\t-C Disable CFO correction [Default %s]\n", args->disable_cfo?"Disabled":"Enabled"); + printf("\t-t Add time offset [Default %d]\n", args->time_offset); #ifndef DISABLE_GRAPHICS printf("\t-d disable plots [Default enabled]\n"); + printf("\t-D disable all but constellation plots [Default enabled]\n"); #else printf("\t plots are disabled. Graphics library not available\n"); #endif @@ -135,7 +148,7 @@ void usage(prog_args_t *args, char *prog) { void parse_args(prog_args_t *args, int argc, char **argv) { int opt; args_default(args); - while ((opt = getopt(argc, argv, "aoglipPcdnvrfuUsS")) != -1) { + while ((opt = getopt(argc, argv, "aoglipPcCtdDnvrfuUsS")) != -1) { switch (opt) { case 'i': args->input_file_name = argv[optind]; @@ -155,6 +168,12 @@ void parse_args(prog_args_t *args, int argc, char **argv) { case 'g': args->uhd_gain = atof(argv[optind]); break; + case 'C': + args->disable_cfo = true; + break; + case 't': + args->time_offset = atoi(argv[optind]); + break; case 'o': args->uhd_freq_offset = atof(argv[optind]); break; @@ -165,7 +184,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) { args->nof_subframes = atoi(argv[optind]); break; case 'r': - args->rnti = atoi(argv[optind]); + args->rnti = strtol(argv[optind], NULL, 16); break; case 'l': args->force_N_id_2 = atoi(argv[optind]); @@ -185,6 +204,9 @@ void parse_args(prog_args_t *args, int argc, char **argv) { case 'd': args->disable_plots = true; break; + case 'D': + args->disable_plots_except_constellation = true; + break; case 'v': srslte_verbose++; break; @@ -373,7 +395,7 @@ int main(int argc, char **argv) { // Variables for measurements uint32_t nframes=0; float rsrp=0.0, rsrq=0.0, snr=0.0; - bool decode_pdsch; + bool decode_pdsch = false; int pdcch_tx=0; #ifndef DISABLE_UHD @@ -381,6 +403,19 @@ int main(int argc, char **argv) { srslte_ue_sync_start_agc(&ue_sync, cuhd_set_rx_gain_th, cell_detect_config.init_agc); } #endif +#ifdef PRINT_CHANGE_SCHEDULIGN + srslte_ra_dl_dci_t old_dl_dci; + bzero(&old_dl_dci, sizeof(srslte_ra_dl_dci_t)); +#endif + + ue_sync.correct_cfo = !prog_args.disable_cfo; + + /* Set high priority */ + struct sched_param param; + param.sched_priority = sched_get_priority_max(SCHED_FIFO); + if (sched_setscheduler(pthread_self(), SCHED_FIFO, ¶m)) { + perror("setscheduler"); + } INFO("\nEntering main loop...\n\n", 0); /* Main loop */ @@ -412,9 +447,13 @@ int main(int argc, char **argv) { break; case DECODE_PDSCH: if (prog_args.rnti != SRSLTE_SIRNTI) { - decode_pdsch = true; + if (srslte_ue_sync_get_sfidx(&ue_sync) != 5 && srslte_ue_sync_get_sfidx(&ue_sync) != 0) { + decode_pdsch = true; + } else { + decode_pdsch = false; + } } else { - /* We are looking for SIB1 Blocks, search only in appropiate places */ + /* We are looking for SIB1 Blocks, 2search only in appropiate places */ if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) { decode_pdsch = true; } else { @@ -423,9 +462,9 @@ int main(int argc, char **argv) { } if (decode_pdsch) { if (prog_args.rnti != SRSLTE_SIRNTI) { - n = srslte_ue_dl_decode(&ue_dl, sf_buffer, data_packed, srslte_ue_sync_get_sfidx(&ue_sync)); + n = srslte_ue_dl_decode(&ue_dl, &sf_buffer[prog_args.time_offset], data_packed, srslte_ue_sync_get_sfidx(&ue_sync)); } else { - n = srslte_ue_dl_decode_rnti_rv(&ue_dl, sf_buffer, data_packed, srslte_ue_sync_get_sfidx(&ue_sync), + n = srslte_ue_dl_decode_rnti_rv(&ue_dl, &sf_buffer[prog_args.time_offset], data_packed, srslte_ue_sync_get_sfidx(&ue_sync), SRSLTE_SIRNTI, ((int) ceilf((float)3*(((sfn)/2)%4)/2))%4); } if (n < 0) { @@ -436,7 +475,22 @@ int main(int argc, char **argv) { srslte_bit_unpack_vector(data_packed, data, n); srslte_netsink_write(&net_sink, data, 1+(n-1)/8); } + + #ifdef PRINT_CHANGE_SCHEDULIGN + if (ue_dl.dl_dci.mcs_idx != old_dl_dci.mcs_idx || + ue_dl.dl_dci.alloc_type != old_dl_dci.alloc_type || + ue_dl.dl_dci.type2_alloc.riv != ue_dl.dl_dci.type2_alloc.riv) + { + memcpy(&old_dl_dci, &ue_dl.dl_dci, sizeof(srslte_ra_dl_dci_t)); + fflush(stdout);printf("\nCFI:\t%d\n", ue_dl.cfi); + printf("Format: %s\n", srslte_dci_format_string(ue_dl.dci_format)); + srslte_ra_pdsch_fprint(stdout, &old_dl_dci, cell.nof_prb); + srslte_ra_dl_grant_fprint(stdout, &ue_dl.pdsch_cfg.grant); + } + #endif + } + nof_trials++; rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&ue_dl.chest), rsrq, 0.05); @@ -507,8 +561,10 @@ int main(int argc, char **argv) { #ifndef DISABLE_GRAPHICS if (!prog_args.disable_plots) { - plot_sf_idx = srslte_ue_sync_get_sfidx(&ue_sync); - sem_post(&plot_sem); + if ((sfn%10) == 0 && decode_pdsch) { + plot_sf_idx = srslte_ue_sync_get_sfidx(&ue_sync); + sem_post(&plot_sem); + } } #endif } else if (ret == 0) { @@ -555,7 +611,7 @@ int main(int argc, char **argv) { //plot_waterfall_t poutfft; -plot_real_t p_sync, pce; +plot_real_t p_sync, pce, pce_arg; plot_scatter_t pscatequal, pscatequal_pdcch; float tmp_plot[SRSLTE_SLOT_LEN_RE(SRSLTE_MAX_PRB, SRSLTE_CP_NORM)]; @@ -566,38 +622,82 @@ void *plot_thread_run(void *arg) { int i; uint32_t nof_re = SRSLTE_SF_LEN_RE(ue_dl.cell.nof_prb, ue_dl.cell.cp); + + sdrgui_init(); + + //plot_waterfall_init(&poutfft, SRSLTE_NRE * ue_dl.cell.nof_prb, 1000); + //plot_waterfall_setTitle(&poutfft, "Output FFT - Magnitude"); + //plot_waterfall_setPlotYAxisScale(&poutfft, -40, 40); + + if (!prog_args.disable_plots_except_constellation) { + plot_real_init(&pce); + plot_real_setTitle(&pce, "Channel Response - Magnitude"); + plot_real_setLabels(&pce, "Index", "dB"); + plot_real_setYAxisScale(&pce, -40, 40); + + #ifdef PLOT_CHEST_ARGUMENT + plot_real_init(&pce_arg); + plot_real_setTitle(&pce_arg, "Channel Response - Argument"); + plot_real_setLabels(&pce_arg, "Index", "rad"); + plot_real_setYAxisScale(&pce_arg, -1.1*M_PI, 1.1*M_PI); + #endif + + plot_real_init(&p_sync); + plot_real_setTitle(&p_sync, "PSS Cross-Corr abs value"); + plot_real_setYAxisScale(&p_sync, 0, 1); + + plot_scatter_init(&pscatequal_pdcch); + plot_scatter_setTitle(&pscatequal_pdcch, "PDCCH - Equalized Symbols"); + plot_scatter_setXAxisScale(&pscatequal_pdcch, -4, 4); + plot_scatter_setYAxisScale(&pscatequal_pdcch, -4, 4); + } + + plot_scatter_init(&pscatequal); + plot_scatter_setTitle(&pscatequal, "PDSCH - Equalized Symbols"); + plot_scatter_setXAxisScale(&pscatequal, -4, 4); + plot_scatter_setYAxisScale(&pscatequal, -4, 4); + + while(1) { sem_wait(&plot_sem); uint32_t nof_symbols = ue_dl.pdsch_cfg.grant.nof_re; - for (i = 0; i < nof_re; i++) { - tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i])); - if (isinf(tmp_plot[i])) { - tmp_plot[i] = -80; + if (!prog_args.disable_plots_except_constellation) { + for (i = 0; i < nof_re; i++) { + tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i])); + if (isinf(tmp_plot[i])) { + tmp_plot[i] = -80; + } } - } - for (i = 0; i < SRSLTE_REFSIGNAL_NUM_SF(ue_dl.cell.nof_prb,0); i++) { - tmp_plot2[i] = 20 * log10f(cabsf(ue_dl.chest.pilot_estimates_average[0][i])); - if (isinf(tmp_plot2[i])) { - tmp_plot2[i] = -80; + for (i = 0; i < SRSLTE_REFSIGNAL_NUM_SF(ue_dl.cell.nof_prb,0); i++) { + tmp_plot2[i] = 20 * log10f(cabsf(ue_dl.chest.pilot_estimates_average[0][i])); + if (isinf(tmp_plot2[i])) { + tmp_plot2[i] = -80; + } } - } - //for (i=0;i 0) { @@ -613,36 +713,17 @@ void *plot_thread_run(void *arg) { void init_plots() { - sdrgui_init(); - - //plot_waterfall_init(&poutfft, SRSLTE_NRE * ue_dl.cell.nof_prb, 1000); - //plot_waterfall_setTitle(&poutfft, "Output FFT - Magnitude"); - //plot_waterfall_setPlotYAxisScale(&poutfft, -40, 40); - - plot_real_init(&pce); - plot_real_setTitle(&pce, "Channel Response - Magnitude"); - plot_real_setLabels(&pce, "Index", "dB"); - plot_real_setYAxisScale(&pce, -40, 40); - - plot_real_init(&p_sync); - plot_real_setTitle(&p_sync, "PSS Cross-Corr abs value"); - plot_real_setYAxisScale(&p_sync, 0, 1); - - plot_scatter_init(&pscatequal); - plot_scatter_setTitle(&pscatequal, "PDSCH - Equalized Symbols"); - plot_scatter_setXAxisScale(&pscatequal, -4, 4); - plot_scatter_setYAxisScale(&pscatequal, -4, 4); - - plot_scatter_init(&pscatequal_pdcch); - plot_scatter_setTitle(&pscatequal_pdcch, "PDCCH - Equalized Symbols"); - plot_scatter_setXAxisScale(&pscatequal_pdcch, -4, 4); - plot_scatter_setYAxisScale(&pscatequal_pdcch, -4, 4); - if (sem_init(&plot_sem, 0, 0)) { perror("sem_init"); exit(-1); } + pthread_attr_t attr; + struct sched_param param; + param.sched_priority = 0; + pthread_attr_init(&attr); + pthread_attr_setschedpolicy(&attr, SCHED_OTHER); + pthread_attr_setschedparam(&attr, ¶m); if (pthread_create(&plot_thread, NULL, plot_thread_run, NULL)) { perror("pthread_create"); exit(-1); diff --git a/srslte/include/srslte/phch/pdsch.h b/srslte/include/srslte/phch/pdsch.h index ec8ae4135..2d0a6227e 100644 --- a/srslte/include/srslte/phch/pdsch.h +++ b/srslte/include/srslte/phch/pdsch.h @@ -48,9 +48,6 @@ #include "srslte/phch/sch.h" #include "srslte/phch/pdsch_cfg.h" -#define SRSLTE_PDSCH_MAX_TDEC_ITERS 5 - - /* PDSCH object */ typedef struct SRSLTE_API { srslte_cell_t cell; diff --git a/srslte/include/srslte/phch/sch.h b/srslte/include/srslte/phch/sch.h index af3abde87..6bca0cccf 100644 --- a/srslte/include/srslte/phch/sch.h +++ b/srslte/include/srslte/phch/sch.h @@ -46,7 +46,7 @@ #include "srslte/phch/pusch_cfg.h" #include "srslte/phch/uci.h" -#define SRSLTE_PDSCH_MAX_TDEC_ITERS 5 +#define SRSLTE_PDSCH_MAX_TDEC_ITERS 2 #ifndef SRSLTE_RX_NULL diff --git a/srslte/include/srslte/ue/ue_dl.h b/srslte/include/srslte/ue/ue_dl.h index 1024e80ca..0093b5429 100644 --- a/srslte/include/srslte/ue/ue_dl.h +++ b/srslte/include/srslte/ue/ue_dl.h @@ -70,7 +70,7 @@ typedef struct SRSLTE_API { srslte_pdsch_cfg_t pdsch_cfg; srslte_softbuffer_rx_t softbuffer; - + srslte_ra_dl_dci_t dl_dci; srslte_cell_t cell; cf_t *sf_symbols; diff --git a/srslte/lib/phch/src/dci.c b/srslte/lib/phch/src/dci.c index 94071a709..cf357390e 100644 --- a/srslte/lib/phch/src/dci.c +++ b/srslte/lib/phch/src/dci.c @@ -680,7 +680,6 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 // rv version srslte_bit_pack(data->rv_idx, &y, 2); - if (crc_is_crnti) { // TPC not implemented y++; diff --git a/srslte/lib/phch/src/pdcch.c b/srslte/lib/phch/src/pdcch.c index 62d5f20a4..c8627ba21 100644 --- a/srslte/lib/phch/src/pdcch.c +++ b/srslte/lib/phch/src/pdcch.c @@ -204,7 +204,7 @@ uint32_t srslte_pdcch_ue_locations(srslte_pdcch_t *q, srslte_dci_location_t *c, k = 0; // All aggregation levels from 8 to 1 - for (l = 3; l >= 0; l--) { + for (l = 0; l < 3; l++) { L = (1 << l); // For all possible ncce offset for (i = 0; i < SRSLTE_MIN(q->nof_cce / L, S[l]/PDCCH_FORMAT_NOF_CCE(l)); i++) { diff --git a/srslte/lib/phch/src/ra.c b/srslte/lib/phch/src/ra.c index 06479ea41..f4ab8e956 100644 --- a/srslte/lib/phch/src/ra.c +++ b/srslte/lib/phch/src/ra.c @@ -369,51 +369,47 @@ static int dl_dci_to_grant_prb_allocation(srslte_ra_dl_dci_t *dci, srslte_ra_dl_ /* Modulation order and transport block size determination 7.1.7 in 36.213 */ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *grant, bool crc_is_crnti) { - uint32_t n_prb; + uint32_t n_prb=0; int tbs = -1; - switch(dci->dci_format) { - case SRSLTE_RA_DCI_FORMAT1: - /* Table 7.1.7.1-1 on 36.213 */ - if (dci->mcs_idx < 10) { - grant->mcs.mod = SRSLTE_MOD_QPSK; - tbs = srslte_ra_tbs_from_idx(dci->mcs_idx, grant->nof_prb); - } else if (dci->mcs_idx < 17) { - grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_16QAM; - tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 1, grant->nof_prb); - } else if (dci->mcs_idx < 29) { - grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_64QAM; - tbs = srslte_ra_tbs_from_idx(dci->mcs_idx - 2, grant->nof_prb); - } else if (dci->mcs_idx == 29) { - grant->mcs.mod = SRSLTE_MOD_QPSK; - tbs = 0; - } else if (dci->mcs_idx == 30) { - grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_16QAM; - tbs = 0; - } else if (dci->mcs_idx == 31) { - grant->mcs.mod = !crc_is_crnti?SRSLTE_MOD_QPSK:SRSLTE_MOD_64QAM; - tbs = 0; - } - break; - case SRSLTE_RA_DCI_FORMAT1A: - /* Downlink Transport Block size determination as defined in 7.1.7.2 on 36.213 */ - if (crc_is_crnti) { - n_prb = grant->nof_prb; - } else { - n_prb = dci->type2_alloc.n_prb1a == SRSLTE_RA_TYPE2_NPRB1A_2 ? 2 : 3; - } - if (dci->mcs_idx < 27 && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) { - tbs = tbs_table[dci->mcs_idx][n_prb - 1]; - grant->mcs.mod = SRSLTE_MOD_QPSK; + uint32_t i_tbs = 0; + + if (!crc_is_crnti) { + if (dci->dci_format == SRSLTE_RA_DCI_FORMAT1A) { + n_prb = dci->type2_alloc.n_prb1a == SRSLTE_RA_TYPE2_NPRB1A_2 ? 2 : 3; + i_tbs = dci->mcs_idx; + } else { + if (dci->mcs_idx < 32) { + tbs = tbs_format1c_table[dci->mcs_idx]; } - break; - case SRSLTE_RA_DCI_FORMAT1C: - /* Downlink Transport Block size for Format 1C as defined in 7.1.7.2.2-1 on 36.213 */ - if (dci->mcs_idx < 32) { - tbs = tbs_format1c_table[dci->mcs_idx]; - grant->mcs.mod = SRSLTE_MOD_QPSK; - } - break; - } + } + grant->mcs.mod = SRSLTE_MOD_QPSK; + } else { + n_prb = grant->nof_prb; + if (dci->mcs_idx < 10) { + grant->mcs.mod = SRSLTE_MOD_QPSK; + i_tbs = dci->mcs_idx; + } else if (dci->mcs_idx < 17) { + grant->mcs.mod = SRSLTE_MOD_16QAM; + i_tbs = dci->mcs_idx-1; + } else if (dci->mcs_idx < 29) { + grant->mcs.mod = SRSLTE_MOD_64QAM; + i_tbs = dci->mcs_idx-2; + } else if (dci->mcs_idx == 29) { + grant->mcs.mod = SRSLTE_MOD_QPSK; + tbs = 0; + i_tbs = 0; + } else if (dci->mcs_idx == 30) { + grant->mcs.mod = SRSLTE_MOD_16QAM; + tbs = 0; + i_tbs = 0; + } else if (dci->mcs_idx == 31) { + grant->mcs.mod = SRSLTE_MOD_64QAM; + tbs = 0; + i_tbs = 0; + } + } + tbs = srslte_ra_tbs_from_idx(i_tbs, n_prb); + if (tbs < 0) { return SRSLTE_ERROR; } else { @@ -534,7 +530,6 @@ int srslte_ra_tbs_from_idx(uint32_t tbs_idx, uint32_t n_prb) { if (tbs_idx < 27 && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) { return tbs_table[tbs_idx][n_prb - 1]; } else { - fprintf(stderr, "Error computing TBS: Invalid TBS_idx=%d or n_prb=%d\n", tbs_idx, n_prb); return SRSLTE_ERROR; } } diff --git a/srslte/lib/ue/src/ue_dl.c b/srslte/lib/ue/src/ue_dl.c index 4b36522e8..2b2acad9b 100644 --- a/srslte/lib/ue/src/ue_dl.c +++ b/srslte/lib/ue/src/ue_dl.c @@ -150,7 +150,7 @@ void srslte_ue_dl_reset(srslte_ue_dl_t *q) { bzero(&q->pdsch_cfg, sizeof(srslte_pdsch_cfg_t)); } -srslte_dci_format_t ue_formats[] = {SRSLTE_DCI_FORMAT1,SRSLTE_DCI_FORMAT1A}; // SRSLTE_DCI_FORMAT1B should go here also +srslte_dci_format_t ue_formats[] = {SRSLTE_DCI_FORMAT1A, SRSLTE_DCI_FORMAT1}; // SRSLTE_DCI_FORMAT1B should go here also const uint32_t nof_ue_formats = 2; srslte_dci_format_t common_formats[] = {SRSLTE_DCI_FORMAT1A,SRSLTE_DCI_FORMAT1C}; @@ -208,10 +208,8 @@ int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_ q->nof_detected++; - srslte_ra_dl_dci_t dl_dci; - - if (srslte_dci_msg_to_dl_grant(dci_msg, rnti, q->cell, cfi, sf_idx, &dl_dci, &q->pdsch_cfg.grant)) { - fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n"); + if (srslte_dci_msg_to_dl_grant(dci_msg, rnti, q->cell, cfi, sf_idx, &q->dl_dci, &q->pdsch_cfg.grant)) { + //fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n"); return SRSLTE_ERROR; } if (srslte_cbsegm(&q->pdsch_cfg.cb_segm, q->pdsch_cfg.grant.mcs.tbs)) { @@ -222,7 +220,10 @@ int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_ if (rnti == SRSLTE_SIRNTI) { q->pdsch_cfg.rv = rvidx; } else { - q->pdsch_cfg.rv = dl_dci.rv_idx; + q->pdsch_cfg.rv = q->dl_dci.rv_idx; + } + if (q->pdsch_cfg.rv == 0) { + srslte_softbuffer_rx_reset(&q->softbuffer); } if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { ret = srslte_pdsch_decode_rnti(&q->pdsch, &q->pdsch_cfg, &q->softbuffer,