diff --git a/srslte/examples/cell_measurement.c b/srslte/examples/cell_measurement.c index 493bbd606..8c9d95fe3 100644 --- a/srslte/examples/cell_measurement.c +++ b/srslte/examples/cell_measurement.c @@ -237,11 +237,11 @@ int main(int argc, char **argv) { srslte_rf_stop_rx_stream(&rf); srslte_rf_flush_buffer(&rf); - if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) { + if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) { fprintf(stderr, "Error initiating ue_sync\n"); return -1; } - if (srslte_ue_dl_init(&ue_dl, cell, 1)) { + if (srslte_ue_dl_init_multi(&ue_dl, cell, 1)) { fprintf(stderr, "Error initiating UE downlink processing module\n"); return -1; } @@ -283,7 +283,7 @@ int main(int argc, char **argv) { /* Main loop */ while ((sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) && !go_exit) { - ret = srslte_ue_sync_zerocopy(&ue_sync, sf_buffer); + ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); } @@ -310,7 +310,7 @@ int main(int argc, char **argv) { case DECODE_SIB: /* We are looking for SI Blocks, search only in appropiate places */ if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) { - n = srslte_ue_dl_decode(&ue_dl, sf_buffer, data, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); + n = srslte_ue_dl_decode_multi(&ue_dl, sf_buffer, data, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); if (n < 0) { fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); return -1; diff --git a/srslte/examples/cell_search.c b/srslte/examples/cell_search.c index ee5704e5a..fc684578a 100644 --- a/srslte/examples/cell_search.c +++ b/srslte/examples/cell_search.c @@ -204,7 +204,7 @@ int main(int argc, char **argv) { bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); - if (srslte_ue_cellsearch_init(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, 1, (void*) &rf)) { + if (srslte_ue_cellsearch_init_multi(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, 1, (void*) &rf)) { fprintf(stderr, "Error initiating UE cell detect\n"); exit(-1); } diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index db9fe7008..373e45449 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -411,7 +411,7 @@ int main(int argc, char **argv) { } else { #ifndef DISABLE_RF - if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, prog_args.rf_nof_rx_ant, (void*) &rf)) { + if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, prog_args.rf_nof_rx_ant, (void*) &rf)) { fprintf(stderr, "Error initiating ue_sync\n"); exit(-1); } @@ -423,7 +423,7 @@ int main(int argc, char **argv) { exit(-1); } - if (srslte_ue_dl_init(&ue_dl, cell, prog_args.rf_nof_rx_ant)) { // This is the User RNTI + if (srslte_ue_dl_init_multi(&ue_dl, cell, prog_args.rf_nof_rx_ant)) { // This is the User RNTI fprintf(stderr, "Error initiating UE downlink processing module\n"); exit(-1); } @@ -478,7 +478,7 @@ int main(int argc, char **argv) { /* Main loop */ while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) { - ret = srslte_ue_sync_zerocopy(&ue_sync, sf_buffer); + ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); } @@ -519,10 +519,10 @@ int main(int argc, char **argv) { } if (decode_pdsch) { INFO("Attempting DL decode SFN=%d\n", sfn); - n = srslte_ue_dl_decode(&ue_dl, - sf_buffer, - data, - sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); + n = srslte_ue_dl_decode_multi(&ue_dl, + sf_buffer, + data, + sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); if (n < 0) { // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); @@ -701,7 +701,7 @@ void *plot_thread_run(void *arg) { uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits.nof_re; if (!prog_args.disable_plots_except_constellation) { for (i = 0; i < nof_re; i++) { - tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[0][i])); + tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i])); if (isinf(tmp_plot[i])) { tmp_plot[i] = -80; } @@ -710,7 +710,7 @@ void *plot_thread_run(void *arg) { bzero(tmp_plot2, sizeof(float)*sz); int g = (sz - 12*ue_dl.cell.nof_prb)/2; for (i = 0; i < 12*ue_dl.cell.nof_prb; i++) { - tmp_plot2[g+i] = 20 * log10(cabs(ue_dl.ce[0][0][i])); + tmp_plot2[g+i] = 20 * log10(cabs(ue_dl.ce[0][i])); if (isinf(tmp_plot2[g+i])) { tmp_plot2[g+i] = -80; } diff --git a/srslte/examples/usrp_capture_sync.c b/srslte/examples/usrp_capture_sync.c index 6059ae626..6e7f74cb6 100644 --- a/srslte/examples/usrp_capture_sync.c +++ b/srslte/examples/usrp_capture_sync.c @@ -158,7 +158,7 @@ int main(int argc, char **argv) { cell.nof_prb = nof_prb; cell.nof_ports = 1; - if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) { + if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) { fprintf(stderr, "Error initiating ue_sync\n"); exit(-1); } @@ -169,7 +169,7 @@ int main(int argc, char **argv) { while((subframe_count < nof_subframes || nof_subframes == -1) && !stop_capture) { - n = srslte_ue_sync_zerocopy(&ue_sync, buffer); + n = srslte_ue_sync_zerocopy_multi(&ue_sync, buffer); if (n < 0) { fprintf(stderr, "Error receiving samples\n"); exit(-1); diff --git a/srslte/include/srslte/ue/ue_cell_search.h b/srslte/include/srslte/ue/ue_cell_search.h index 6b53fe925..628683f09 100644 --- a/srslte/include/srslte/ue/ue_cell_search.h +++ b/srslte/include/srslte/ue/ue_cell_search.h @@ -83,10 +83,15 @@ typedef struct SRSLTE_API { SRSLTE_API int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t *q, uint32_t max_frames_total, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), - uint32_t nof_rx_antennas, + int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), void *stream_handler); +SRSLTE_API int srslte_ue_cellsearch_init_multi(srslte_ue_cellsearch_t *q, + uint32_t max_frames_total, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler); + SRSLTE_API void srslte_ue_cellsearch_free(srslte_ue_cellsearch_t *q); SRSLTE_API int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t *q, diff --git a/srslte/include/srslte/ue/ue_dl.h b/srslte/include/srslte/ue/ue_dl.h index 1f29ea8d5..a32794aa2 100644 --- a/srslte/include/srslte/ue/ue_dl.h +++ b/srslte/include/srslte/ue/ue_dl.h @@ -90,8 +90,10 @@ typedef struct SRSLTE_API { uint32_t nof_rx_antennas; - cf_t *sf_symbols[SRSLTE_MAX_PORTS]; - cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; + cf_t *sf_symbols; // this is for backwards compatibility + cf_t *sf_symbols_m[SRSLTE_MAX_PORTS]; + cf_t *ce[SRSLTE_MAX_PORTS]; // compatibility + cf_t *ce_m[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; srslte_dci_format_t dci_format; uint64_t pkt_errors; @@ -112,12 +114,20 @@ typedef struct SRSLTE_API { /* This function shall be called just after the initial synchronization */ SRSLTE_API int srslte_ue_dl_init(srslte_ue_dl_t *q, - srslte_cell_t cell, - uint32_t nof_rx_antennas); + srslte_cell_t cell); + +SRSLTE_API int srslte_ue_dl_init_multi(srslte_ue_dl_t *q, + srslte_cell_t cell, + uint32_t nof_rx_antennas); SRSLTE_API void srslte_ue_dl_free(srslte_ue_dl_t *q); SRSLTE_API int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, + cf_t *input, + uint32_t sf_idx, + uint32_t *cfi); + +SRSLTE_API int srslte_ue_dl_decode_fft_estimate_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t *cfi); @@ -157,16 +167,27 @@ SRSLTE_API void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, float sample_offset); SRSLTE_API int srslte_ue_dl_decode(srslte_ue_dl_t * q, - cf_t *input[SRSLTE_MAX_PORTS], + cf_t *input, uint8_t *data, uint32_t tti); +SRSLTE_API int srslte_ue_dl_decode_multi(srslte_ue_dl_t * q, + cf_t *input[SRSLTE_MAX_PORTS], + uint8_t *data, + uint32_t tti); + SRSLTE_API int srslte_ue_dl_decode_rnti(srslte_ue_dl_t * q, - cf_t *input[SRSLTE_MAX_PORTS], + cf_t *input, uint8_t *data, uint32_t tti, uint16_t rnti); +SRSLTE_API int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t * q, + cf_t *input[SRSLTE_MAX_PORTS], + uint8_t *data, + uint32_t tti, + uint16_t rnti); + SRSLTE_API bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_prb_lowest, diff --git a/srslte/include/srslte/ue/ue_mib.h b/srslte/include/srslte/ue/ue_mib.h index e31102a13..202b6ee7f 100644 --- a/srslte/include/srslte/ue/ue_mib.h +++ b/srslte/include/srslte/ue/ue_mib.h @@ -107,10 +107,16 @@ typedef struct { SRSLTE_API int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, uint32_t cell_id, srslte_cp_t cp, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t *), - uint32_t nof_rx_antennas, + int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t *), void *stream_handler); +SRSLTE_API int srslte_ue_mib_sync_init_multi(srslte_ue_mib_sync_t *q, + uint32_t cell_id, + srslte_cp_t cp, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t *), + uint32_t nof_rx_antennas, + void *stream_handler); + SRSLTE_API void srslte_ue_mib_sync_free(srslte_ue_mib_sync_t *q); SRSLTE_API void srslte_ue_mib_sync_reset(srslte_ue_mib_sync_t * q); diff --git a/srslte/include/srslte/ue/ue_sync.h b/srslte/include/srslte/ue/ue_sync.h index 2483aa1a2..04efe3c18 100644 --- a/srslte/include/srslte/ue/ue_sync.h +++ b/srslte/include/srslte/ue/ue_sync.h @@ -75,7 +75,8 @@ typedef struct SRSLTE_API { uint32_t agc_period; void *stream; - int (*recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*); + int (*recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*); + int (*recv_callback_single)(void*, void*, uint32_t, srslte_timestamp_t*); srslte_timestamp_t last_timestamp; uint32_t nof_rx_antennas; @@ -115,19 +116,24 @@ typedef struct SRSLTE_API { float mean_sfo; uint32_t sample_offset_correct_period; float sfo_ema; + #ifdef MEASURE_EXEC_TIME float mean_exec_time; #endif } srslte_ue_sync_t; - SRSLTE_API int srslte_ue_sync_init(srslte_ue_sync_t *q, srslte_cell_t cell, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), - uint32_t nof_rx_antennas, + int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*), void *stream_handler); +SRSLTE_API int srslte_ue_sync_init_multi(srslte_ue_sync_t *q, + srslte_cell_t cell, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler); + SRSLTE_API int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_name, @@ -147,7 +153,10 @@ SRSLTE_API void srslte_ue_sync_set_agc_period(srslte_ue_sync_t *q, /* CAUTION: input_buffer MUST have space for 2 subframes */ SRSLTE_API int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, - cf_t *input_buffer[SRSLTE_MAX_PORTS]); + cf_t *input_buffer); + +SRSLTE_API int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, + cf_t *input_buffer[SRSLTE_MAX_PORTS]); SRSLTE_API void srslte_ue_sync_set_cfo(srslte_ue_sync_t *q, float cfo); diff --git a/srslte/lib/phch/test/pdsch_pdcch_file_test.c b/srslte/lib/phch/test/pdsch_pdcch_file_test.c index f31cc38da..0d19d689e 100644 --- a/srslte/lib/phch/test/pdsch_pdcch_file_test.c +++ b/srslte/lib/phch/test/pdsch_pdcch_file_test.c @@ -137,7 +137,7 @@ int base_init() { exit(-1); } - if (srslte_ue_dl_init(&ue_dl, cell, 1)) { + if (srslte_ue_dl_init_multi(&ue_dl, cell, 1)) { fprintf(stderr, "Error initializing UE DL\n"); return -1; } @@ -177,7 +177,7 @@ int main(int argc, char **argv) { srslte_filesource_read(&fsrc, input_buffer, flen); INFO("Reading %d samples sub-frame %d\n", flen, sf_idx); - ret = srslte_ue_dl_decode(&ue_dl, &input_buffer, data, sf_idx); + ret = srslte_ue_dl_decode(&ue_dl, input_buffer, data, sf_idx); if(ret > 0) { printf("PDSCH Decoded OK!\n"); } else if (ret == 0) { diff --git a/srslte/lib/rf/rf_utils.c b/srslte/lib/rf/rf_utils.c index 1f0a7d74e..10c6b53df 100644 --- a/srslte/lib/rf/rf_utils.c +++ b/srslte/lib/rf/rf_utils.c @@ -103,7 +103,7 @@ int rf_mib_decoder(srslte_rf_t *rf, uint32_t nof_rx_antennas,cell_search_cfg_t * srslte_ue_mib_sync_t ue_mib; uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; - if (srslte_ue_mib_sync_init(&ue_mib, cell->id, cell->cp, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { + if (srslte_ue_mib_sync_init_multi(&ue_mib, cell->id, cell->cp, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { fprintf(stderr, "Error initiating srslte_ue_mib_sync\n"); goto clean_exit; } @@ -164,7 +164,7 @@ int rf_cell_search(srslte_rf_t *rf, uint32_t nof_rx_antennas, bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); - if (srslte_ue_cellsearch_init(&cs, config->max_frames_pss, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { + if (srslte_ue_cellsearch_init_multi(&cs, config->max_frames_pss, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { fprintf(stderr, "Error initiating UE cell detect\n"); return SRSLTE_ERROR; } diff --git a/srslte/lib/ue/ue_cell_search.c b/srslte/lib/ue/ue_cell_search.c index 2306dc606..868af36b9 100644 --- a/srslte/lib/ue/ue_cell_search.c +++ b/srslte/lib/ue/ue_cell_search.c @@ -36,6 +36,59 @@ #include "srslte/utils/vector.h" int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t * q, uint32_t max_frames, + int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), + void *stream_handler) +{ + int ret = SRSLTE_ERROR_INVALID_INPUTS; + + if (q != NULL) { + ret = SRSLTE_ERROR; + srslte_cell_t cell; + + bzero(q, sizeof(srslte_ue_cellsearch_t)); + + bzero(&cell, sizeof(srslte_cell_t)); + cell.id = SRSLTE_CELL_ID_UNKNOWN; + cell.nof_prb = SRSLTE_CS_NOF_PRB; + + if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, stream_handler)) { + fprintf(stderr, "Error initiating ue_sync\n"); + goto clean_exit; + } + + q->sf_buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100)); + q->nof_rx_antennas = 1; + + q->candidates = calloc(sizeof(srslte_ue_cellsearch_result_t), max_frames); + if (!q->candidates) { + perror("malloc"); + goto clean_exit; + } + q->mode_ntimes = calloc(sizeof(uint32_t), max_frames); + if (!q->mode_ntimes) { + perror("malloc"); + goto clean_exit; + } + q->mode_counted = calloc(sizeof(uint8_t), max_frames); + if (!q->mode_counted) { + perror("malloc"); + goto clean_exit; + } + + q->max_frames = max_frames; + q->nof_valid_frames = max_frames; + + ret = SRSLTE_SUCCESS; + } + +clean_exit: + if (ret == SRSLTE_ERROR) { + srslte_ue_cellsearch_free(q); + } + return ret; +} + +int srslte_ue_cellsearch_init_multi(srslte_ue_cellsearch_t * q, uint32_t max_frames, int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), uint32_t nof_rx_antennas, void *stream_handler) @@ -52,7 +105,7 @@ int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t * q, uint32_t max_frames, cell.id = SRSLTE_CELL_ID_UNKNOWN; cell.nof_prb = SRSLTE_CS_NOF_PRB; - if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { + if (srslte_ue_sync_init_multi(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); goto clean_exit; } @@ -226,7 +279,7 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, srslte_ue_sync_reset(&q->ue_sync); do { - ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer); + ret = srslte_ue_sync_zerocopy_multi(&q->ue_sync, q->sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); break; diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 01569bc56..bd98802c0 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -44,10 +44,15 @@ const uint32_t nof_ue_formats = 2; static srslte_dci_format_t common_formats[] = {SRSLTE_DCI_FORMAT1A,SRSLTE_DCI_FORMAT1C}; const uint32_t nof_common_formats = 2; - int srslte_ue_dl_init(srslte_ue_dl_t *q, - srslte_cell_t cell, - uint32_t nof_rx_antennas) + srslte_cell_t cell) +{ + return srslte_ue_dl_init_multi(q, cell, 1); +} + +int srslte_ue_dl_init_multi(srslte_ue_dl_t *q, + srslte_cell_t cell, + uint32_t nof_rx_antennas) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -107,20 +112,25 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, srslte_cfo_set_tol(&q->sfo_correct, 1e-5/q->fft.symbol_sz); for (int j=0;jsf_symbols[j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); - if (!q->sf_symbols[j]) { + q->sf_symbols_m[j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); + if (!q->sf_symbols_m[j]) { perror("malloc"); goto clean_exit; } for (uint32_t i=0;icell.nof_ports;i++) { - q->ce[i][j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); - if (!q->ce[i][j]) { + q->ce_m[i][j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); + if (!q->ce_m[i][j]) { perror("malloc"); goto clean_exit; } } } + q->sf_symbols = q->sf_symbols_m[0]; + for (int i=0;icell.nof_ports;i++) { + q->ce[i] = q->ce_m[i][0]; + } + ret = SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid cell properties: Id=%d, Ports=%d, PRBs=%d\n", @@ -146,12 +156,12 @@ void srslte_ue_dl_free(srslte_ue_dl_t *q) { srslte_cfo_free(&q->sfo_correct); srslte_softbuffer_rx_free(&q->softbuffer); for (int j=0;jnof_rx_antennas;j++) { - if (q->sf_symbols[j]) { - free(q->sf_symbols[j]); + if (q->sf_symbols_m[j]) { + free(q->sf_symbols_m[j]); } for (uint32_t i=0;icell.nof_ports;i++) { - if (q->ce[i][j]) { - free(q->ce[i][j]); + if (q->ce_m[i][j]) { + free(q->ce_m[i][j]); } } } @@ -193,23 +203,37 @@ void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, float sample_offset) { * - PDCCH decoding: Find DCI for RNTI given by previous call to srslte_ue_dl_set_rnti() * - PDSCH decoding: Decode TB scrambling with RNTI given by srslte_ue_dl_set_rnti() */ -int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint8_t *data, uint32_t tti) { - return srslte_ue_dl_decode_rnti(q, input, data, tti, q->current_rnti); +int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti) { + cf_t *_input[SRSLTE_MAX_PORTS]; + _input[0] = input; + return srslte_ue_dl_decode_rnti_multi(q, _input, data, tti, q->current_rnti); } -int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t *cfi) { +int srslte_ue_dl_decode_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint8_t *data, uint32_t tti) { + return srslte_ue_dl_decode_rnti_multi(q, input, data, tti, q->current_rnti); +} + +int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input, uint32_t sf_idx, uint32_t *cfi) +{ + cf_t *_input[SRSLTE_MAX_PORTS]; + _input[0] = input; + return srslte_ue_dl_decode_fft_estimate_multi(q, _input, sf_idx, cfi); +} + +int srslte_ue_dl_decode_fft_estimate_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t *cfi) +{ if (input && q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) { /* Run FFT for all subframe data */ for (int j=0;jnof_rx_antennas;j++) { - srslte_ofdm_rx_sf(&q->fft, input[j], q->sf_symbols[j]); + srslte_ofdm_rx_sf(&q->fft, input[j], q->sf_symbols_m[j]); /* Correct SFO multiplying by complex exponential in the time domain */ if (q->sample_offset) { for (int i=0;i<2*SRSLTE_CP_NSYMB(q->cell.cp);i++) { srslte_cfo_correct(&q->sfo_correct, - &q->sf_symbols[j][i*q->cell.nof_prb*SRSLTE_NRE], - &q->sf_symbols[j][i*q->cell.nof_prb*SRSLTE_NRE], + &q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE], + &q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE], q->sample_offset / q->fft.symbol_sz); } } @@ -225,10 +249,10 @@ int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t *c if (q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) { /* Get channel estimates for each port */ - srslte_chest_dl_estimate_multi(&q->chest, q->sf_symbols, q->ce, sf_idx, q->nof_rx_antennas); + srslte_chest_dl_estimate_multi(&q->chest, q->sf_symbols_m, q->ce_m, sf_idx, q->nof_rx_antennas); /* First decode PCFICH and obtain CFI */ - if (srslte_pcfich_decode_multi(&q->pcfich, q->sf_symbols, q->ce, + if (srslte_pcfich_decode_multi(&q->pcfich, q->sf_symbols_m, q->ce_m, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi, &cfi_corr)<0) { fprintf(stderr, "Error decoding PCFICH\n"); @@ -254,7 +278,14 @@ int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint3 return srslte_pdsch_cfg(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx); } -int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint8_t *data, uint32_t tti, uint16_t rnti) +int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti, uint16_t rnti) +{ + cf_t *_input[SRSLTE_MAX_PORTS]; + _input[0] = input; + return srslte_ue_dl_decode_rnti_multi(q, _input, data, tti, rnti); +} + +int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint8_t *data, uint32_t tti, uint16_t rnti) { srslte_dci_msg_t dci_msg; srslte_ra_dl_dci_t dci_unpacked; @@ -264,7 +295,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], u uint32_t sf_idx = tti%10; - if ((ret = srslte_ue_dl_decode_fft_estimate(q, input, sf_idx, &cfi)) < 0) { + if ((ret = srslte_ue_dl_decode_fft_estimate_multi(q, input, sf_idx, &cfi)) < 0) { return ret; } @@ -272,7 +303,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], u // Uncoment next line to do ZF by default in pdsch_ue example //float noise_estimate = 0; - if (srslte_pdcch_extract_llr_multi(&q->pdcch, q->sf_symbols, q->ce, noise_estimate, sf_idx, cfi)) { + if (srslte_pdcch_extract_llr_multi(&q->pdcch, q->sf_symbols_m, q->ce_m, noise_estimate, sf_idx, cfi)) { fprintf(stderr, "Error extracting LLRs\n"); return SRSLTE_ERROR; } @@ -310,7 +341,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], u if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { ret = srslte_pdsch_decode_multi(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, - q->sf_symbols, q->ce, + q->sf_symbols_m, q->ce_m, noise_estimate, rnti, data); @@ -515,11 +546,11 @@ bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_pr cf_t *ce0[SRSLTE_MAX_PORTS]; for (int i=0;ice[i][0]; + ce0[i] = q->ce_m[i][0]; } - if (!srslte_phich_decode(&q->phich, q->sf_symbols[0], ce0, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { + if (!srslte_phich_decode(&q->phich, q->sf_symbols_m[0], ce0, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { INFO("Decoded PHICH %d with distance %f\n", ack_bit, distance); } else { fprintf(stderr, "Error decoding PHICH\n"); @@ -533,11 +564,11 @@ bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_pr } void srslte_ue_dl_save_signal(srslte_ue_dl_t *q, srslte_softbuffer_rx_t *softbuffer, uint32_t tti, uint32_t rv_idx, uint16_t rnti, uint32_t cfi) { - srslte_vec_save_file("sf_symbols", q->sf_symbols, SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); + srslte_vec_save_file("sf_symbols", q->sf_symbols_m, SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); printf("%d samples\n", SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)); - srslte_vec_save_file("ce0", q->ce[0], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); + srslte_vec_save_file("ce0", q->ce_m[0], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); if (q->cell.nof_ports > 1) { - srslte_vec_save_file("ce1", q->ce[1], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); + srslte_vec_save_file("ce1", q->ce_m[1], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); } srslte_vec_save_file("pcfich_ce0", q->pcfich.ce[0], q->pcfich.nof_symbols*sizeof(cf_t)); srslte_vec_save_file("pcfich_ce1", q->pcfich.ce[1], q->pcfich.nof_symbols*sizeof(cf_t)); diff --git a/srslte/lib/ue/ue_mib.c b/srslte/lib/ue/ue_mib.c index bf0b97ce2..9b5b4e9ef 100644 --- a/srslte/lib/ue/ue_mib.c +++ b/srslte/lib/ue/ue_mib.c @@ -161,13 +161,10 @@ int srslte_ue_mib_decode(srslte_ue_mib_t * q, cf_t *input, return ret; } - - int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, uint32_t cell_id, srslte_cp_t cp, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), - uint32_t nof_rx_antennas, + int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*), void *stream_handler) { srslte_cell_t cell; @@ -177,6 +174,36 @@ int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, cell.cp = cp; cell.nof_prb = SRSLTE_UE_MIB_NOF_PRB; + q->sf_buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); + q->nof_rx_antennas = 1; + + if (srslte_ue_mib_init(&q->ue_mib, cell)) { + fprintf(stderr, "Error initiating ue_mib\n"); + return SRSLTE_ERROR; + } + if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, stream_handler)) { + fprintf(stderr, "Error initiating ue_sync\n"); + srslte_ue_mib_free(&q->ue_mib); + return SRSLTE_ERROR; + } + srslte_ue_sync_decode_sss_on_track(&q->ue_sync, true); + return SRSLTE_SUCCESS; +} + +int srslte_ue_mib_sync_init_multi(srslte_ue_mib_sync_t *q, + uint32_t cell_id, + srslte_cp_t cp, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler) +{ + srslte_cell_t cell; + // If the ports are set to 0, ue_mib goes through 1, 2 and 4 ports to blindly detect nof_ports + cell.nof_ports = 0; + cell.id = cell_id; + cell.cp = cp; + cell.nof_prb = SRSLTE_UE_MIB_NOF_PRB; + for (int i=0;isf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); } @@ -186,7 +213,7 @@ int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, fprintf(stderr, "Error initiating ue_mib\n"); return SRSLTE_ERROR; } - if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { + if (srslte_ue_sync_init_multi(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); srslte_ue_mib_free(&q->ue_mib); return SRSLTE_ERROR; @@ -226,7 +253,7 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t * q, ret = SRSLTE_SUCCESS; do { mib_ret = SRSLTE_UE_MIB_NOTFOUND; - ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer); + ret = srslte_ue_sync_zerocopy_multi(&q->ue_sync, q->sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); break; diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index 70eec60be..4cf61bbb3 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -106,11 +106,26 @@ int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(voi return n; } +int recv_callback_multi_to_single(void *h, cf_t *x[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t*t) +{ + srslte_ue_sync_t *q = (srslte_ue_sync_t*) h; + return q->recv_callback_single(q->stream, (void*) x[0], nsamples, t); +} + int srslte_ue_sync_init(srslte_ue_sync_t *q, srslte_cell_t cell, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), - uint32_t nof_rx_antennas, + int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), void *stream_handler) +{ + q->recv_callback_single = recv_callback; + return srslte_ue_sync_init_multi(q, cell, recv_callback_multi_to_single, 1, q); +} + +int srslte_ue_sync_init_multi(srslte_ue_sync_t *q, + srslte_cell_t cell, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -459,8 +474,14 @@ static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PO bool first_track = true; +int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { + cf_t *_input_buffer[SRSLTE_MAX_PORTS]; + _input_buffer[0] = input_buffer; + return srslte_ue_sync_zerocopy_multi(q, _input_buffer); +} + /* Returns 1 if the subframe is synchronized in time, 0 otherwise */ -int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PORTS]) { +int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PORTS]) { int ret = SRSLTE_ERROR_INVALID_INPUTS; uint32_t track_idx;