From 99df252279926c90bdc3b8afcf6154a281db51d9 Mon Sep 17 00:00:00 2001 From: ismagom Date: Mon, 2 Mar 2015 11:11:44 +0100 Subject: [PATCH] Fixed PRACH example --- cuhd/include/liblte/cuhd/cuhd.h | 50 +++- cuhd/lib/cuhd_imp.cpp | 112 ++++---- lte/examples/cell_measurement.c | 2 +- lte/examples/pdsch_ue.c | 2 +- lte/examples/prach_ue.c | 75 ++++-- lte/phy/include/liblte/phy/phch/pdsch.h | 14 + lte/phy/include/liblte/phy/phch/pusch.h | 13 + lte/phy/include/liblte/phy/ue/ue_dl.h | 7 + lte/phy/lib/ch_estimation/src/refsignal_ul.c | 3 - lte/phy/lib/phch/src/pdsch.c | 257 +++++++++++-------- lte/phy/lib/phch/src/pusch.c | 111 +++++--- lte/phy/lib/sync/test/pss_usrp.c | 30 ++- lte/phy/lib/ue/src/ue_dl.c | 28 +- matlab/tests/drms_pusch_test.m | 1 + 14 files changed, 454 insertions(+), 251 deletions(-) diff --git a/cuhd/include/liblte/cuhd/cuhd.h b/cuhd/include/liblte/cuhd/cuhd.h index bf15fce25..a78288424 100644 --- a/cuhd/include/liblte/cuhd/cuhd.h +++ b/cuhd/include/liblte/cuhd/cuhd.h @@ -65,17 +65,9 @@ LIBLTE_API double cuhd_set_rx_freq_offset(void *h, double freq, double off); -LIBLTE_API int cuhd_recv(void *h, - void *data, - uint32_t nsamples, - bool blocking); - -LIBLTE_API int cuhd_recv_timed(void *h, - void *data, - uint32_t nsamples, - bool blocking, - time_t *secs, - double *frac_secs); +LIBLTE_API void cuhd_get_time(void *h, + time_t *secs, + double *frac_secs); LIBLTE_API double cuhd_set_tx_srate(void *h, double freq); @@ -93,6 +85,32 @@ LIBLTE_API double cuhd_set_tx_freq_offset(void *h, double freq, double off); + +LIBLTE_API int cuhd_recv(void *h, + void *data, + uint32_t nsamples, + bool blocking); + +LIBLTE_API int cuhd_recv_with_time(void *h, + void *data, + uint32_t nsamples, + time_t *secs, + double *frac_secs); + +LIBLTE_API int cuhd_recv_timed(void *h, + void *data, + uint32_t nsamples, + time_t secs, + double frac_secs); + +LIBLTE_API int cuhd_recv_timed2(void *h, + void *data, + uint32_t nsamples, + time_t secs, + double frac_secs, + bool is_start_of_burst, + bool is_end_of_burst); + LIBLTE_API int cuhd_send(void *h, void *data, uint32_t nsamples, @@ -102,10 +120,18 @@ LIBLTE_API int cuhd_send(void *h, LIBLTE_API int cuhd_send_timed(void *h, void *data, int nsamples, - int blocking, time_t secs, double frac_secs); +LIBLTE_API int cuhd_send_timed2(void *h, + void *data, + int nsamples, + time_t secs, + double frac_secs, + bool is_start_of_burst, + bool is_end_of_burst); + + #ifdef __cplusplus } #endif diff --git a/cuhd/lib/cuhd_imp.cpp b/cuhd/lib/cuhd_imp.cpp index b3650988f..719100fa1 100644 --- a/cuhd/lib/cuhd_imp.cpp +++ b/cuhd/lib/cuhd_imp.cpp @@ -156,11 +156,12 @@ double cuhd_set_rx_srate(void *h, double freq) handler->usrp->set_rx_rate(freq); double ret = handler->usrp->get_rx_rate(); + /* if ((int) ret != (int) freq) { handler->usrp->set_master_clock_rate(freq); handler->usrp->set_rx_rate(freq); } - + */ return freq; } @@ -213,39 +214,56 @@ int cuhd_recv(void *h, void *data, uint32_t nsamples, bool blocking) } } -int cuhd_recv_timed(void *h, - void *data, - uint32_t nsamples, - bool blocking, - time_t *secs, - double *frac_secs) +int cuhd_recv_with_time(void *h, + void *data, + uint32_t nsamples, + time_t *secs, + double *frac_secs) { cuhd_handler* handler = static_cast(h); uhd::rx_metadata_t md; - *secs = -1; - *frac_secs = -1; - int p; - if (blocking) { - int n=0; - complex_t *data_c = (complex_t*) data; - do { - p=handler->rx_stream->recv(&data_c[n], nsamples-n, md); - if (p == -1) { - return -1; - } - if(*secs < 0){ - *secs = md.time_spec.get_full_secs(); - *frac_secs = md.time_spec.get_frac_secs(); - } - n+=p; - } while(nrx_stream->recv(data, nsamples, md, 0.0); + int p = handler->rx_stream->recv(data, nsamples, md, 0.0); + if (secs && frac_secs) { *secs = md.time_spec.get_full_secs(); - *frac_secs = md.time_spec.get_frac_secs(); - return p; + *frac_secs = md.time_spec.get_frac_secs(); } + return p; +} + +int cuhd_recv_timed(void *h, + void *data, + uint32_t nsamples, + time_t secs, + double frac_secs) +{ + return cuhd_recv_timed2(h, data, nsamples, secs, frac_secs, true, true); +} + + +int cuhd_recv_timed2(void *h, + void *data, + uint32_t nsamples, + time_t secs, + double frac_secs, + bool is_start_of_burst, + bool is_end_of_burst) +{ + cuhd_handler* handler = static_cast(h); + uhd::rx_metadata_t md; + md.start_of_burst = is_start_of_burst; + md.end_of_burst = is_end_of_burst; + md.has_time_spec = true; + md.time_spec = uhd::time_spec_t(secs, frac_secs); + + return handler->rx_stream->recv(data, nsamples, md); +} + +void cuhd_get_time(void *h, time_t *secs, double *frac_secs) +{ + cuhd_handler* handler = static_cast(h); + uhd::time_spec_t now = handler->usrp->get_time_now(); + *secs = now.get_full_secs(); + *frac_secs = now.get_frac_secs(); } void cuhd_set_tx_antenna(void *h, char *name) @@ -301,32 +319,28 @@ int cuhd_send(void *h, void *data, uint32_t nsamples, bool blocking) } } - int cuhd_send_timed(void *h, void *data, int nsamples, - int blocking, time_t secs, - double frac_secs) { + double frac_secs) +{ + return cuhd_send_timed2(h, data, nsamples, secs, frac_secs, true, true); +} + +int cuhd_send_timed2(void *h, + void *data, + int nsamples, + time_t secs, + double frac_secs, + bool is_start_of_burst, + bool is_end_of_burst) +{ cuhd_handler* handler = static_cast(h); uhd::tx_metadata_t md; - md.start_of_burst = true; - md.end_of_burst = true; + md.start_of_burst = is_start_of_burst; + md.end_of_burst = is_end_of_burst; md.has_time_spec = true; md.time_spec = uhd::time_spec_t(secs, frac_secs); - if (blocking) { - int n=0,p; - complex_t *data_c = (complex_t*) data; - do { - p=handler->tx_stream->send(&data_c[n], nsamples-n, md); - md.has_time_spec = false; - if (p == -1) { - return -1; - } - n+=p; - } while(ntx_stream->send(data, nsamples, md, 0.0); - } + return handler->tx_stream->send(data, nsamples, md); } diff --git a/lte/examples/cell_measurement.c b/lte/examples/cell_measurement.c index 364f3d097..6e1ae4ee9 100644 --- a/lte/examples/cell_measurement.c +++ b/lte/examples/cell_measurement.c @@ -261,7 +261,7 @@ int main(int argc, char **argv) { case DECODE_SIB: /* We are looking for SI Blocks, search only in appropiate places */ if ((ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) { - n = ue_dl_decode_sib(&ue_dl, sf_buffer, data, ue_sync_get_sfidx(&ue_sync), + n = ue_dl_decode_sib(&ue_dl, sf_buffer, data, ue_sync_get_sfidx(&ue_sync), SIRNTI, ((int) ceilf((float)3*(((sfn)/2)%4)/2))%4); if (n < 0) { fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); diff --git a/lte/examples/pdsch_ue.c b/lte/examples/pdsch_ue.c index 9d3feb1df..2d372354a 100644 --- a/lte/examples/pdsch_ue.c +++ b/lte/examples/pdsch_ue.c @@ -394,7 +394,7 @@ int main(int argc, char **argv) { if (prog_args.rnti != SIRNTI) { n = ue_dl_decode(&ue_dl, sf_buffer, data_packed, ue_sync_get_sfidx(&ue_sync)); } else { - n = ue_dl_decode_sib(&ue_dl, sf_buffer, data_packed, ue_sync_get_sfidx(&ue_sync), + n = ue_dl_decode_sib(&ue_dl, sf_buffer, data_packed, ue_sync_get_sfidx(&ue_sync), SIRNTI, ((int) ceilf((float)3*(((sfn)/2)%4)/2))%4); } if (n < 0) { diff --git a/lte/examples/prach_ue.c b/lte/examples/prach_ue.c index 72f871e44..155ba2079 100644 --- a/lte/examples/prach_ue.c +++ b/lte/examples/prach_ue.c @@ -151,7 +151,7 @@ void sig_int_handler(int signo) int cuhd_recv_wrapper_timed(void *h, void *data, uint32_t nsamples, timestamp_t *uhd_time) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return cuhd_recv_timed(h, data, nsamples, 1, &uhd_time->full_secs, &uhd_time->frac_secs); + return cuhd_recv_with_time(h, data, nsamples, &uhd_time->full_secs, &uhd_time->frac_secs); } extern float mean_exec_time; @@ -291,7 +291,7 @@ int rar_to_ra_pusch(rar_msg_t *rar, ra_pusch_t *ra, uint32_t nof_prb) { } ra->type2_alloc.riv = riv; ra->mcs_idx = rar->mcs; - printf("b: %d, RIV: %d\n", b, riv); + ra_type2_from_riv(riv, &ra->type2_alloc.L_crb, &ra->type2_alloc.RB_start, nof_prb, nof_prb); @@ -315,7 +315,8 @@ int main(int argc, char **argv) { timestamp_t uhd_time; timestamp_t next_tx_time; const uint8_t conn_request_msg[] = {0x20, 0x06, 0x1F, 0x5C, 0x2C, 0x04, 0xB2, 0xAC, 0xF6}; - + uint8_t data[100]; + parse_args(&prog_args, argc, argv); printf("Opening UHD device...\n"); @@ -383,8 +384,9 @@ int main(int argc, char **argv) { refsignal_ul_t drms; refsignal_drms_pusch_cfg_t pusch_cfg; - pusch_cfg.nof_prb = 3; bzero(&pusch_cfg, sizeof(refsignal_drms_pusch_cfg_t)); + pusch_cfg.nof_prb = 3; + pusch_cfg.beta_pusch = 1.0; if (refsignal_ul_init(&drms, cell)) { fprintf(stderr, "Error initiating refsignal_ul\n"); exit(-1); @@ -395,7 +397,9 @@ int main(int argc, char **argv) { exit(-1); } for (uint32_t i=0;i<2;i++) { - refsignal_dmrs_pusch_gen(&drms, &pusch_cfg, 2*4+i, &drms_signal[i*RE_X_RB*pusch_cfg.nof_prb]); + if (refsignal_dmrs_pusch_gen(&drms, &pusch_cfg, 2*4+i, &drms_signal[i*RE_X_RB*pusch_cfg.nof_prb])) { + fprintf(stderr, "Error generating PUSCH DRMS signals\n"); + } } if (pusch_init(&pusch, cell)) { @@ -420,7 +424,7 @@ int main(int argc, char **argv) { exit(-1); } bzero(ul_signal, sizeof(cf_t) * SF_LEN_PRB(cell.nof_prb)); - + cf_t *sf_symbols = vec_malloc(sizeof(cf_t) * SF_LEN_PRB(cell.nof_prb)); if (!sf_symbols) { perror("malloc"); @@ -444,10 +448,11 @@ int main(int argc, char **argv) { // Register Ctrl+C handler signal(SIGINT, sig_int_handler); - + cuhd_start_rx_stream(uhd); struct timeval tdata[3]; + uint16_t ra_rnti; /* Main loop */ while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) { @@ -485,11 +490,10 @@ int main(int argc, char **argv) { timestamp_add(&next_tx_time, 0, 0.01); // send next frame (10 ms) printf("Send prach sfn: %d. Last frame time = %.6f, send prach time = %.6f\n", sfn, timestamp_real(&uhd_time), timestamp_real(&next_tx_time)); - cuhd_send_timed(uhd, prach_buffers[7], prach_buffer_len, 1, + cuhd_send_timed(uhd, prach_buffers[7], prach_buffer_len, next_tx_time.full_secs, next_tx_time.frac_secs); - uint16_t ra_rnti = 2; - ue_dl_set_rnti(&ue_dl, ra_rnti); + ra_rnti = 2; rar_window_start = sfn+1; rar_window_stop = sfn+3; state = RECV_RAR; @@ -499,29 +503,32 @@ int main(int argc, char **argv) { if ((sfn == rar_window_start && ue_sync_get_sfidx(&ue_sync) > 3) || sfn > rar_window_start) { gettimeofday(&tdata[1], NULL); printf("Looking for RAR in sfn: %d sf_idx: %d\n", sfn, ue_sync_get_sfidx(&ue_sync)); - n = ue_dl_decode(&ue_dl, sf_buffer, data_rx, ue_sync_get_sfidx(&ue_sync)); + n = ue_dl_decode_rnti(&ue_dl, sf_buffer, data_rx, ra_rnti, ue_sync_get_sfidx(&ue_sync)); if (n < 0) { fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); } else if (n > 0) { - printf("RAR received %d bits: ", n); - vec_fprint_hex(stdout, data_rx, n); + + gettimeofday(&tdata[2], NULL); + get_time_interval(tdata); + printf("time exec DL: %d\n",tdata[0].tv_usec); + + gettimeofday(&tdata[1], NULL); + rar_unpack(data_rx, &rar_msg); rar_msg_fprint(stdout, &rar_msg); - pusch_set_rnti(&pusch, rar_msg.temp_c_rnti); - rar_to_ra_pusch(&rar_msg, &ra_pusch, cell.nof_prb); ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb); ra_ul_alloc(&prb_alloc, &ra_pusch, 0, cell.nof_prb); - printf("Sending ConnectionRequest in sfn: %d sf_idx: %d\n", sfn, ue_sync_get_sfidx(&ue_sync)); - verbose=VERBOSE_INFO; if (harq_setup_ul(&pusch_harq, ra_pusch.mcs, 0, (ue_sync_get_sfidx(&ue_sync)+6)%10, &prb_alloc)) { fprintf(stderr, "Error configuring HARQ process\n"); exit(-1);; } - if (pusch_encode(&pusch, &pusch_harq, (uint8_t*) conn_request_msg, sf_symbols)) { + + bit_pack_vector((uint8_t*) conn_request_msg, data, ra_pusch.mcs.tbs); + if (pusch_encode_rnti(&pusch, &pusch_harq, data, rar_msg.temp_c_rnti, sf_symbols)) { fprintf(stderr, "Error encoding TB\n"); exit(-1); } @@ -531,16 +538,32 @@ int main(int argc, char **argv) { lte_ifft_run_sf(&fft, sf_symbols, ul_signal); - ue_sync_get_last_timestamp(&ue_sync, &uhd_time); - timestamp_copy(&next_tx_time, &uhd_time); - timestamp_add(&next_tx_time, 0, 0.006); // send after 6 sub-frames (6 ms) - printf("Send PUSCH sfn: %d. Last frame time = %.6f, send PUSCH time = %.6f\n", - sfn, timestamp_real(&uhd_time), timestamp_real(&next_tx_time)); gettimeofday(&tdata[2], NULL); get_time_interval(tdata); - printf("time exec: %d\n",tdata[0].tv_usec); - cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb), 1, - next_tx_time.full_secs, next_tx_time.frac_secs); + printf("time exec UL: %d\n",tdata[0].tv_usec); + + gettimeofday(&tdata[1], NULL); + cuhd_stop_rx_stream(uhd); + cuhd_flush_buffer(uhd); + gettimeofday(&tdata[2], NULL); + get_time_interval(tdata); + printf("time to stop RX: %d\n",tdata[0].tv_usec); + + ue_sync_get_last_timestamp(&ue_sync, &uhd_time); + + float time_adv_sec = ((float) rar_msg.timing_adv_cmd - 31 - 25) * 16 /(15000*2048); + + vec_sc_prod_cfc(ul_signal, 2, ul_signal, SF_LEN_PRB(cell.nof_prb)); + + vec_fprint_c(stdout, sf_symbols, 300); + + timestamp_copy(&next_tx_time, &uhd_time); + timestamp_add(&next_tx_time, 0, 0.006 + time_adv_sec); // send after 6 sub-frames (6 ms) + printf("Send %d samples PUSCH sfn: %d. Last frame time = %.6f, send PUSCH time = %.6f TA: %f\n", + SF_LEN_PRB(cell.nof_prb), sfn, timestamp_real(&uhd_time), timestamp_real(&next_tx_time), time_adv_sec); + cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb), + next_tx_time.full_secs, next_tx_time.frac_secs); + go_exit = 1; } if (sfn >= rar_window_stop) { diff --git a/lte/phy/include/liblte/phy/phch/pdsch.h b/lte/phy/include/liblte/phy/phch/pdsch.h index fc58e9672..4da8af9b2 100644 --- a/lte/phy/include/liblte/phy/phch/pdsch.h +++ b/lte/phy/include/liblte/phy/phch/pdsch.h @@ -84,6 +84,12 @@ LIBLTE_API int pdsch_encode(pdsch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS]); +LIBLTE_API int pdsch_encode_rnti(pdsch_t *q, + harq_t *harq_process, + uint8_t *data, + uint16_t rnti, + cf_t *sf_symbols[MAX_PORTS]); + LIBLTE_API int pdsch_decode(pdsch_t *q, harq_t *harq_process, cf_t *sf_symbols, @@ -91,6 +97,14 @@ LIBLTE_API int pdsch_decode(pdsch_t *q, float noise_estimate, uint8_t *data); +LIBLTE_API int pdsch_decode_rnti(pdsch_t *q, + harq_t *harq_process, + cf_t *sf_symbols, + cf_t *ce[MAX_PORTS], + float noise_estimate, + uint16_t rnti, + uint8_t *data); + LIBLTE_API float pdsch_average_noi(pdsch_t *q); LIBLTE_API uint32_t pdsch_last_noi(pdsch_t *q); diff --git a/lte/phy/include/liblte/phy/phch/pusch.h b/lte/phy/include/liblte/phy/phch/pusch.h index b898d8fa5..f3cf0e4cd 100644 --- a/lte/phy/include/liblte/phy/phch/pusch.h +++ b/lte/phy/include/liblte/phy/phch/pusch.h @@ -92,12 +92,25 @@ LIBLTE_API int pusch_encode(pusch_t *q, uint8_t *data, cf_t *sf_symbols); +LIBLTE_API int pusch_encode_rnti(pusch_t *q, + harq_t *harq_process, + uint8_t *data, + uint16_t rnti, + cf_t *sf_symbols); + LIBLTE_API int pusch_uci_encode(pusch_t *q, harq_t *harq_process, uint8_t *data, uci_data_t uci_data, cf_t *sf_symbols); +LIBLTE_API int pusch_uci_encode_rnti(pusch_t *q, + harq_t *harq, + uint8_t *data, + uci_data_t uci_data, + uint16_t rnti, + cf_t *sf_symbols); + LIBLTE_API int pusch_decode(pusch_t *q, harq_t *harq_process, cf_t *sf_symbols, diff --git a/lte/phy/include/liblte/phy/ue/ue_dl.h b/lte/phy/include/liblte/phy/ue/ue_dl.h index ebac41afc..360758265 100644 --- a/lte/phy/include/liblte/phy/ue/ue_dl.h +++ b/lte/phy/include/liblte/phy/ue/ue_dl.h @@ -89,10 +89,17 @@ LIBLTE_API int ue_dl_decode(ue_dl_t * q, uint8_t *data, uint32_t sf_idx); +LIBLTE_API int ue_dl_decode_rnti(ue_dl_t * q, + cf_t *input, + uint8_t *data, + uint16_t rnti, + uint32_t sf_idx); + LIBLTE_API int ue_dl_decode_sib(ue_dl_t * q, cf_t *input, uint8_t * data, uint32_t sf_idx, + uint16_t rnti, uint32_t rvidx); LIBLTE_API void ue_dl_reset(ue_dl_t *q); diff --git a/lte/phy/lib/ch_estimation/src/refsignal_ul.c b/lte/phy/lib/ch_estimation/src/refsignal_ul.c index ad10b3969..3323d2c60 100644 --- a/lte/phy/lib/ch_estimation/src/refsignal_ul.c +++ b/lte/phy/lib/ch_estimation/src/refsignal_ul.c @@ -284,13 +284,10 @@ int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, u, v, alpha, N_sz, get_q(u,v,N_sz)); } - vec_fprint_f(stdout, q->tmp_arg, RE_X_RB*cfg->nof_prb); - // Do complex exponential and adjust amplitude for (int i=0;inof_prb;i++) { r_pusch[i] = cfg->beta_pusch * cexpf(I*(q->tmp_arg[i] + alpha*i)); } - vec_fprint_c(stdout, r_pusch, RE_X_RB*cfg->nof_prb); ret = 0; } return ret; diff --git a/lte/phy/lib/phch/src/pdsch.c b/lte/phy/lib/phch/src/pdsch.c index a7ef6e539..4a3272ef0 100644 --- a/lte/phy/lib/phch/src/pdsch.c +++ b/lte/phy/lib/phch/src/pdsch.c @@ -302,6 +302,10 @@ void pdsch_free(pdsch_t *q) { } +/* Precalculate the PUSCH scramble sequences for a given RNTI. This function takes a while + * to execute, so shall be called once the final C-RNTI has been allocated for the session. + * For the connection procedure, use pusch_encode_rnti() or pusch_decode_rnti() functions + */ int pdsch_set_rnti(pdsch_t *q, uint16_t rnti) { uint32_t i; for (i = 0; i < NSUBFRAMES_X_FRAME; i++) { @@ -315,10 +319,27 @@ int pdsch_set_rnti(pdsch_t *q, uint16_t rnti) { return LIBLTE_SUCCESS; } +int pdsch_decode(pdsch_t *q, harq_t *harq, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_estimate, uint8_t *data) { + if (q != NULL && + sf_symbols != NULL && + data != NULL && + harq != NULL) + { + if (q->rnti_is_set) { + return pdsch_decode_rnti(q, harq, sf_symbols, ce, noise_estimate, q->rnti, data); + } else { + fprintf(stderr, "Must call pdsch_set_rnti() before calling pdsch_decode()\n"); + return LIBLTE_ERROR; + } + } else { + return LIBLTE_ERROR_INVALID_INPUTS; + } +} /** Decodes the PDSCH from the received symbols */ -int pdsch_decode(pdsch_t *q, harq_t *harq, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_estimate, uint8_t *data) +int pdsch_decode_rnti(pdsch_t *q, harq_t *harq, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], + float noise_estimate, uint16_t rnti, uint8_t *data) { /* Set pointers for layermapping & precoding */ @@ -331,71 +352,90 @@ int pdsch_decode(pdsch_t *q, harq_t *harq, cf_t *sf_symbols, cf_t *ce[MAX_PORTS] harq != NULL) { - if (q->rnti_is_set) { + INFO("Decoding PDSCH SF: %d, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", + harq->sf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); - INFO("Decoding PDSCH SF: %d, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", - harq->sf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); - - /* number of layers equals number of ports */ - for (i = 0; i < q->cell.nof_ports; i++) { - x[i] = q->pdsch_x[i]; - } - memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); - - /* extract symbols */ - n = pdsch_get(q, sf_symbols, q->pdsch_symbols[0], &harq->dl_alloc, harq->sf_idx); + /* number of layers equals number of ports */ + for (i = 0; i < q->cell.nof_ports; i++) { + x[i] = q->pdsch_x[i]; + } + memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); + + /* extract symbols */ + n = pdsch_get(q, sf_symbols, q->pdsch_symbols[0], &harq->dl_alloc, harq->sf_idx); + if (n != harq->nof_re) { + fprintf(stderr, "Error expecting %d symbols but got %d\n", harq->nof_re, n); + return LIBLTE_ERROR; + } + + /* extract channel estimates */ + for (i = 0; i < q->cell.nof_ports; i++) { + n = pdsch_get(q, ce[i], q->ce[i], &harq->dl_alloc, harq->sf_idx); if (n != harq->nof_re) { fprintf(stderr, "Error expecting %d symbols but got %d\n", harq->nof_re, n); return LIBLTE_ERROR; } - - /* extract channel estimates */ - for (i = 0; i < q->cell.nof_ports; i++) { - n = pdsch_get(q, ce[i], q->ce[i], &harq->dl_alloc, harq->sf_idx); - if (n != harq->nof_re) { - fprintf(stderr, "Error expecting %d symbols but got %d\n", harq->nof_re, n); - return LIBLTE_ERROR; - } - } - - /* TODO: only diversity is supported */ - if (q->cell.nof_ports == 1) { - /* no need for layer demapping */ - predecoding_single(&q->precoding, q->pdsch_symbols[0], q->ce[0], q->pdsch_d, - harq->nof_re, noise_estimate); - } else { - predecoding_diversity(&q->precoding, q->pdsch_symbols[0], q->ce, x, q->cell.nof_ports, - harq->nof_re, noise_estimate); - layerdemap_diversity(x, q->pdsch_d, q->cell.nof_ports, - harq->nof_re / q->cell.nof_ports); - } - - /* demodulate symbols - * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation, - * thus we don't need tot set it in the LLRs normalization - */ - demod_soft_sigma_set(&q->demod, sqrt(0.5)); - demod_soft_table_set(&q->demod, &q->mod[harq->mcs.mod]); - demod_soft_demodulate(&q->demod, q->pdsch_d, q->pdsch_e, harq->nof_re); - - /* descramble */ - scrambling_f_offset(&q->seq_pdsch[harq->sf_idx], q->pdsch_e, 0, harq->nof_bits); - - return dlsch_decode(&q->dl_sch, harq, q->pdsch_e, data); - } else { - fprintf(stderr, "Must call pdsch_set_rnti() before calling pdsch_decode()\n"); - return LIBLTE_ERROR; } + /* TODO: only diversity is supported */ + if (q->cell.nof_ports == 1) { + /* no need for layer demapping */ + predecoding_single(&q->precoding, q->pdsch_symbols[0], q->ce[0], q->pdsch_d, + harq->nof_re, noise_estimate); + } else { + predecoding_diversity(&q->precoding, q->pdsch_symbols[0], q->ce, x, q->cell.nof_ports, + harq->nof_re, noise_estimate); + layerdemap_diversity(x, q->pdsch_d, q->cell.nof_ports, + harq->nof_re / q->cell.nof_ports); + } + + /* demodulate symbols + * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation, + * thus we don't need tot set it in the LLRs normalization + */ + demod_soft_sigma_set(&q->demod, sqrt(0.5)); + demod_soft_table_set(&q->demod, &q->mod[harq->mcs.mod]); + demod_soft_demodulate(&q->demod, q->pdsch_d, q->pdsch_e, harq->nof_re); + + /* descramble */ + if (rnti != q->rnti) { + sequence_t seq; + if (sequence_pdsch(&seq, rnti, 0, 2 * harq->sf_idx, q->cell.id, harq->nof_bits)) { + return LIBLTE_ERROR; + } + scrambling_f_offset(&seq, q->pdsch_e, 0, harq->nof_bits); + sequence_free(&seq); + } else { + scrambling_f_offset(&q->seq_pdsch[harq->sf_idx], q->pdsch_e, 0, harq->nof_bits); + } + + return dlsch_decode(&q->dl_sch, harq, q->pdsch_e, data); + } else { return LIBLTE_ERROR_INVALID_INPUTS; } } +int pdsch_encode(pdsch_t *q, harq_t *harq, uint8_t *data, cf_t *sf_symbols[MAX_PORTS]) +{ + if (q != NULL && + data != NULL && + harq != NULL) + { + if (q->rnti_is_set) { + return pdsch_encode_rnti(q, harq, data, q->rnti, sf_symbols); + } else { + fprintf(stderr, "Must call pdsch_set_rnti() to set the encoder/decoder RNTI\n"); + return LIBLTE_ERROR; + } + } else { + return LIBLTE_ERROR_INVALID_INPUTS; + } +} /** Converts the PDSCH data bits to symbols mapped to the slot ready for transmission */ -int pdsch_encode(pdsch_t *q, harq_t *harq, uint8_t *data, cf_t *sf_symbols[MAX_PORTS]) +int pdsch_encode_rnti(pdsch_t *q, harq_t *harq, uint8_t *data, uint16_t rnti, cf_t *sf_symbols[MAX_PORTS]) { int i; /* Set pointers for layermapping & precoding */ @@ -407,64 +447,69 @@ int pdsch_encode(pdsch_t *q, harq_t *harq, uint8_t *data, cf_t *sf_symbols[MAX_P harq != NULL) { - if (q->rnti_is_set) { - for (i=0;icell.nof_ports;i++) { - if (sf_symbols[i] == NULL) { - return LIBLTE_ERROR_INVALID_INPUTS; - } - } - - if (harq->mcs.tbs == 0) { - return LIBLTE_ERROR_INVALID_INPUTS; - } - - if (harq->mcs.tbs > harq->nof_bits) { - fprintf(stderr, "Invalid code rate %.2f\n", (float) harq->mcs.tbs / harq->nof_bits); + for (i=0;icell.nof_ports;i++) { + if (sf_symbols[i] == NULL) { return LIBLTE_ERROR_INVALID_INPUTS; } - - if (harq->nof_re > q->max_re) { - fprintf(stderr, - "Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n", - harq->nof_re, q->max_re, q->cell.nof_prb); - return LIBLTE_ERROR_INVALID_INPUTS; - } - - INFO("Encoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", - harq->sf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); - - /* number of layers equals number of ports */ - for (i = 0; i < q->cell.nof_ports; i++) { - x[i] = q->pdsch_x[i]; - } - memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); - - if (dlsch_encode(&q->dl_sch, harq, data, q->pdsch_e)) { - fprintf(stderr, "Error encoding TB\n"); - return LIBLTE_ERROR; - } - - scrambling_b_offset(&q->seq_pdsch[harq->sf_idx], (uint8_t*) q->pdsch_e, 0, harq->nof_bits); - - mod_modulate(&q->mod[harq->mcs.mod], (uint8_t*) q->pdsch_e, q->pdsch_d, harq->nof_bits); - - /* TODO: only diversity supported */ - if (q->cell.nof_ports > 1) { - layermap_diversity(q->pdsch_d, x, q->cell.nof_ports, harq->nof_re); - precoding_diversity(&q->precoding, x, q->pdsch_symbols, q->cell.nof_ports, - harq->nof_re / q->cell.nof_ports); - } else { - memcpy(q->pdsch_symbols[0], q->pdsch_d, harq->nof_re * sizeof(cf_t)); - } - - /* mapping to resource elements */ - for (i = 0; i < q->cell.nof_ports; i++) { - pdsch_put(q, q->pdsch_symbols[i], sf_symbols[i], &harq->dl_alloc, harq->sf_idx); - } - ret = LIBLTE_SUCCESS; - } else { - fprintf(stderr, "Must call pdsch_set_rnti() to set the encoder/decoder RNTI\n"); } + + if (harq->mcs.tbs == 0) { + return LIBLTE_ERROR_INVALID_INPUTS; + } + + if (harq->mcs.tbs > harq->nof_bits) { + fprintf(stderr, "Invalid code rate %.2f\n", (float) harq->mcs.tbs / harq->nof_bits); + return LIBLTE_ERROR_INVALID_INPUTS; + } + + if (harq->nof_re > q->max_re) { + fprintf(stderr, + "Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n", + harq->nof_re, q->max_re, q->cell.nof_prb); + return LIBLTE_ERROR_INVALID_INPUTS; + } + + INFO("Encoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", + harq->sf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); + + /* number of layers equals number of ports */ + for (i = 0; i < q->cell.nof_ports; i++) { + x[i] = q->pdsch_x[i]; + } + memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); + + if (dlsch_encode(&q->dl_sch, harq, data, q->pdsch_e)) { + fprintf(stderr, "Error encoding TB\n"); + return LIBLTE_ERROR; + } + + if (rnti != q->rnti) { + sequence_t seq; + if (sequence_pdsch(&seq, rnti, 0, 2 * harq->sf_idx, q->cell.id, harq->nof_bits)) { + return LIBLTE_ERROR; + } + scrambling_b_offset(&seq, (uint8_t*) q->pdsch_e, 0, harq->nof_bits); + sequence_free(&seq); + } else { + scrambling_b_offset(&q->seq_pdsch[harq->sf_idx], (uint8_t*) q->pdsch_e, 0, harq->nof_bits); + } + + mod_modulate(&q->mod[harq->mcs.mod], (uint8_t*) q->pdsch_e, q->pdsch_d, harq->nof_bits); + + /* TODO: only diversity supported */ + if (q->cell.nof_ports > 1) { + layermap_diversity(q->pdsch_d, x, q->cell.nof_ports, harq->nof_re); + precoding_diversity(&q->precoding, x, q->pdsch_symbols, q->cell.nof_ports, + harq->nof_re / q->cell.nof_ports); + } else { + memcpy(q->pdsch_symbols[0], q->pdsch_d, harq->nof_re * sizeof(cf_t)); + } + + /* mapping to resource elements */ + for (i = 0; i < q->cell.nof_ports; i++) { + pdsch_put(q, q->pdsch_symbols[i], sf_symbols[i], &harq->dl_alloc, harq->sf_idx); + } + ret = LIBLTE_SUCCESS; } return ret; } diff --git a/lte/phy/lib/phch/src/pusch.c b/lte/phy/lib/phch/src/pusch.c index 0346ef5ed..c365e1615 100644 --- a/lte/phy/lib/phch/src/pusch.c +++ b/lte/phy/lib/phch/src/pusch.c @@ -278,6 +278,9 @@ void pusch_free(pusch_t *q) { } +/* Precalculate the PUSCH scramble sequences for a given RNTI. This function takes a while + * to execute, so shall be called once the final C-RNTI has been allocated for the session. + * For the connection procedure, use pusch_encode_rnti() or pusch_decode_rnti() functions */ int pusch_set_rnti(pusch_t *q, uint16_t rnti) { uint32_t i; @@ -292,7 +295,6 @@ int pusch_set_rnti(pusch_t *q, uint16_t rnti) { return LIBLTE_SUCCESS; } - /** Decodes the PUSCH from the received symbols */ int pusch_decode(pusch_t *q, harq_t *harq, cf_t *sf_symbols, cf_t *ce, float noise_estimate, uint8_t *data) @@ -351,16 +353,38 @@ int pusch_decode(pusch_t *q, harq_t *harq, cf_t *sf_symbols, cf_t *ce, float noi } } -int pusch_encode(pusch_t *q, harq_t *harq_process, uint8_t *data, cf_t *sf_symbols) +int pusch_encode_rnti(pusch_t *q, harq_t *harq_process, uint8_t *data, uint16_t rnti, cf_t *sf_symbols) { uci_data_t uci_data; bzero(&uci_data, sizeof(uci_data_t)); - return pusch_uci_encode(q, harq_process, data, uci_data, sf_symbols); + return pusch_uci_encode_rnti(q, harq_process, data, uci_data, rnti, sf_symbols); +} + +int pusch_encode(pusch_t *q, harq_t *harq_process, uint8_t *data, cf_t *sf_symbols) +{ + if (q->rnti_is_set) { + uci_data_t uci_data; + bzero(&uci_data, sizeof(uci_data_t)); + return pusch_uci_encode_rnti(q, harq_process, data, uci_data, q->rnti, sf_symbols); + } else { + fprintf(stderr, "Must call pusch_set_rnti() to set the encoder/decoder RNTI\n"); + return LIBLTE_ERROR; + } +} + +int pusch_uci_encode(pusch_t *q, harq_t *harq, uint8_t *data, uci_data_t uci_data, cf_t *sf_symbols) +{ + if (q->rnti_is_set) { + return pusch_uci_encode_rnti(q, harq, data, uci_data, q->rnti, sf_symbols); + } else { + fprintf(stderr, "Must call pusch_set_rnti() to set the encoder/decoder RNTI\n"); + return LIBLTE_ERROR; + } } /** Converts the PUSCH data bits to symbols mapped to the slot ready for transmission */ -int pusch_uci_encode(pusch_t *q, harq_t *harq, uint8_t *data, uci_data_t uci_data, cf_t *sf_symbols) +int pusch_uci_encode_rnti(pusch_t *q, harq_t *harq, uint8_t *data, uci_data_t uci_data, uint16_t rnti, cf_t *sf_symbols) { int ret = LIBLTE_ERROR_INVALID_INPUTS; @@ -368,41 +392,52 @@ int pusch_uci_encode(pusch_t *q, harq_t *harq, uint8_t *data, uci_data_t uci_dat data != NULL && harq != NULL) { - if (q->rnti_is_set) { - - if (harq->mcs.tbs > harq->nof_bits) { - fprintf(stderr, "Invalid code rate %.2f\n", (float) harq->mcs.tbs / harq->nof_bits); - return LIBLTE_ERROR_INVALID_INPUTS; - } - - if (harq->nof_re > q->max_re) { - fprintf(stderr, "Error too many RE per subframe (%d). PUSCH configured for %d RE (%d PRB)\n", - harq->nof_re, q->max_re, q->cell.nof_prb); - return LIBLTE_ERROR_INVALID_INPUTS; - } - - INFO("Encoding PUSCH SF: %d, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", - harq->sf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); - - if (ulsch_uci_encode(&q->dl_sch, harq, data, uci_data, q->pusch_g, q->pusch_q)) { - fprintf(stderr, "Error encoding TB\n"); - return LIBLTE_ERROR; - } - - scrambling_b_offset_pusch(&q->seq_pusch[harq->sf_idx], (uint8_t*) q->pusch_q, 0, harq->nof_bits); - - mod_modulate(&q->mod[harq->mcs.mod], (uint8_t*) q->pusch_q, q->pusch_d, harq->nof_bits); - - dft_precoding(&q->dft_precoding, q->pusch_d, q->pusch_z, - harq->ul_alloc.L_prb, harq->nof_symb); - - /* mapping to resource elements */ - pusch_put(q, harq, q->pusch_z, sf_symbols); - - ret = LIBLTE_SUCCESS; - } else { - fprintf(stderr, "Must call pusch_set_rnti() to set the encoder/decoder RNTI\n"); + if (harq->mcs.tbs > harq->nof_bits) { + fprintf(stderr, "Invalid code rate %.2f\n", (float) harq->mcs.tbs / harq->nof_bits); + return LIBLTE_ERROR_INVALID_INPUTS; } + + if (harq->nof_re > q->max_re) { + fprintf(stderr, "Error too many RE per subframe (%d). PUSCH configured for %d RE (%d PRB)\n", + harq->nof_re, q->max_re, q->cell.nof_prb); + return LIBLTE_ERROR_INVALID_INPUTS; + } + + INFO("Encoding PUSCH SF: %d, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", + harq->sf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); + + bzero(q->pusch_q, harq->nof_bits); + if (ulsch_uci_encode(&q->dl_sch, harq, data, uci_data, q->pusch_g, q->pusch_q)) { + fprintf(stderr, "Error encoding TB\n"); + return LIBLTE_ERROR; + } + + printf("before scram: "); + vec_fprint_b(stdout, q->pusch_q, harq->nof_bits); + + if (rnti != q->rnti) { + sequence_t seq; + if (sequence_pusch(&seq, rnti, 2 * harq->sf_idx, q->cell.id, harq->nof_bits)) { + return LIBLTE_ERROR; + } + scrambling_b_offset_pusch(&seq, (uint8_t*) q->pusch_q, 0, harq->nof_bits); + sequence_free(&seq); + } else { + scrambling_b_offset_pusch(&q->seq_pusch[harq->sf_idx], (uint8_t*) q->pusch_q, 0, harq->nof_bits); + } + + printf("after scram: "); + vec_fprint_b(stdout, q->pusch_q, harq->nof_bits); + + mod_modulate(&q->mod[harq->mcs.mod], (uint8_t*) q->pusch_q, q->pusch_d, harq->nof_bits); + + dft_precoding(&q->dft_precoding, q->pusch_d, q->pusch_z, + harq->ul_alloc.L_prb, harq->nof_symb); + + /* mapping to resource elements */ + pusch_put(q, harq, q->pusch_z, sf_symbols); + + ret = LIBLTE_SUCCESS; } return ret; } diff --git a/lte/phy/lib/sync/test/pss_usrp.c b/lte/phy/lib/sync/test/pss_usrp.c index fac32e19e..cfbe03894 100644 --- a/lte/phy/lib/sync/test/pss_usrp.c +++ b/lte/phy/lib/sync/test/pss_usrp.c @@ -194,7 +194,6 @@ int main(int argc, char **argv) { frame_cnt = 0; last_peak = 0; mean_peak = 0; - int peak_offset = 0; float cfo; float mean_cfo = 0; uint32_t m0, m1; @@ -205,12 +204,27 @@ int main(int argc, char **argv) { bzero(&ssync, sizeof(sync_t)); ssync.fft_size = fft_size; + + timestamp_t cur_time; + cuhd_get_time(uhd, &cur_time.full_secs, &cur_time.frac_secs); + + // wait 1 sec to start + timestamp_add(&cur_time, 1, 0); + double period = 0.005; // 5 ms + double period_diff = 0; + double nsamples_offset_x_sf; + + int last_peak_idx = 0; + bool is_first = true; while(frame_cnt < nof_frames || nof_frames == -1) { - n = cuhd_recv(uhd, buffer, flen - peak_offset, 1); + timestamp_add(&cur_time, 0, period + period_diff); + + n = cuhd_recv_timed2(uhd, buffer, flen, cur_time.full_secs, cur_time.frac_secs, is_first, false); if (n < 0) { fprintf(stderr, "Error receiving samples\n"); exit(-1); } + is_first = false; peak_idx = pss_synch_find_pss(&pss, buffer, &peak_value); if (peak_idx < 0) { @@ -222,7 +236,13 @@ int main(int argc, char **argv) { if (peak_value >= threshold) { nof_det++; - + + if (last_peak_idx) { + nsamples_offset_x_sf = VEC_CMA(((double) peak_idx - (double) last_peak_idx ), nsamples_offset_x_sf, frame_cnt); + period_diff += nsamples_offset_x_sf / (flen*2*100); + } + last_peak_idx = peak_idx; + if (peak_idx >= fft_size) { // Estimate CFO @@ -288,10 +308,10 @@ int main(int argc, char **argv) { frame_cnt++; - printf("[%5d]: Pos: %5d, PSR: %4.1f (~%4.1f) Pdet: %4.2f, " + printf("[%5d]: Pos: %5d (%f), PSR: %4.1f (~%4.1f) Pdet: %4.2f, " "FA: %4.2f, CFO: %+4.1f KHz SSSmiss: %4.2f/%4.2f/%4.2f CPNorm: %.0f\%\r", frame_cnt, - peak_idx, + peak_idx, period_diff*1000000, peak_value, mean_peak, (float) nof_det/frame_cnt, (float) nof_nopeakdet/frame_cnt, mean_cfo*15, diff --git a/lte/phy/lib/ue/src/ue_dl.c b/lte/phy/lib/ue/src/ue_dl.c index 5013dd228..3ecf5709f 100644 --- a/lte/phy/lib/ue/src/ue_dl.c +++ b/lte/phy/lib/ue/src/ue_dl.c @@ -142,6 +142,10 @@ void ue_dl_free(ue_dl_t *q) { } } +/* Precalculate the PDSCH scramble sequences for a given RNTI. This function takes a while + * to execute, so shall be called once the final C-RNTI has been allocated for the session. + * For the connection procedure, use pusch_encode_rnti() or pusch_decode_rnti() functions + */ void ue_dl_set_rnti(ue_dl_t *q, uint16_t rnti) { q->current_rnti = rnti; pdsch_set_rnti(&q->pdsch, rnti); @@ -167,10 +171,14 @@ const uint32_t nof_common_formats = 2; * - PDSCH decoding: Decode TB scrambling with RNTI given by ue_dl_set_rnti() */ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx) { - return ue_dl_decode_sib(q, input, data, sf_idx, 0); + return ue_dl_decode_sib(q, input, data, sf_idx, q->current_rnti, 0); } -int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32_t rvidx) +int ue_dl_decode_rnti(ue_dl_t *q, cf_t *input, uint8_t *data, uint16_t rnti, uint32_t sf_idx) { + return ue_dl_decode_sib(q, input, data, sf_idx, rnti, 0); +} + +int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) { uint32_t cfi, i; float cfi_corr; @@ -207,12 +215,12 @@ int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, ui } /* Generate PDCCH candidates */ - if (q->current_rnti == SIRNTI) { + if (rnti == SIRNTI) { nof_locations = pdcch_common_locations(&q->pdcch, locations, MAX_CANDIDATES, cfi); formats = common_formats; nof_formats = nof_common_formats; } else { - nof_locations = pdcch_ue_locations(&q->pdcch, locations, MAX_CANDIDATES, sf_idx, cfi, q->current_rnti); + nof_locations = pdcch_ue_locations(&q->pdcch, locations, MAX_CANDIDATES, sf_idx, cfi, rnti); formats = ue_formats; nof_formats = nof_ue_formats; } @@ -233,16 +241,16 @@ int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, ui } INFO("Decoded DCI message RNTI: 0x%x\n", crc_rem); - if (crc_rem == q->current_rnti) { + if (crc_rem == rnti) { found_dci++; q->nof_pdcch_detected++; - if (dci_msg_to_ra_dl(&dci_msg, q->current_rnti, q->cell, cfi, &ra_dl)) { + if (dci_msg_to_ra_dl(&dci_msg, rnti, q->cell, cfi, &ra_dl)) { fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n"); return LIBLTE_ERROR; } - if (q->current_rnti != SIRNTI) { + if (rnti != SIRNTI) { rvidx = ra_dl.rv_idx; } if (harq_setup_dl(&q->harq_process[0], ra_dl.mcs, rvidx, sf_idx, &ra_dl.prb_alloc)) { @@ -250,9 +258,9 @@ int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, ui return LIBLTE_ERROR; } if (q->harq_process[0].mcs.mod > 0 && q->harq_process[0].mcs.tbs >= 0) { - ret = pdsch_decode(&q->pdsch, &q->harq_process[0], q->sf_symbols, - q->ce, chest_dl_get_noise_estimate(&q->chest), - data); + ret = pdsch_decode_rnti(&q->pdsch, &q->harq_process[0], q->sf_symbols, + q->ce, chest_dl_get_noise_estimate(&q->chest), + rnti, data); if (ret == LIBLTE_ERROR) { q->pkt_errors++; } else if (ret == LIBLTE_ERROR_INVALID_INPUTS) { diff --git a/matlab/tests/drms_pusch_test.m b/matlab/tests/drms_pusch_test.m index 506a25533..c5859af27 100644 --- a/matlab/tests/drms_pusch_test.m +++ b/matlab/tests/drms_pusch_test.m @@ -35,6 +35,7 @@ for prb=3 if (error(k) > 10^-3) k=1; end + read_real k=k+1; end end