diff --git a/lte/phy/examples/CMakeLists.txt b/lte/phy/examples/CMakeLists.txt index 5238328c8..a599920ec 100644 --- a/lte/phy/examples/CMakeLists.txt +++ b/lte/phy/examples/CMakeLists.txt @@ -51,12 +51,6 @@ LIST(FIND OPTIONAL_LIBS graphics GRAPHICS_FIND) # These two can be compiled without UHD or graphics support ################################################################# -add_executable(pbch_ue pbch_ue.c) -target_link_libraries(pbch_ue lte_phy) - -add_executable(pbch_enodeb pbch_enodeb.c) -target_link_libraries(pbch_enodeb lte_phy) - add_executable(pdsch_ue pdsch_ue.c) target_link_libraries(pdsch_ue lte_phy) @@ -64,25 +58,17 @@ add_executable(pdsch_enodeb pdsch_enodeb.c) target_link_libraries(pdsch_enodeb lte_phy) IF(${CUHD_FIND} EQUAL -1) - SET_TARGET_PROPERTIES(pbch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD") - SET_TARGET_PROPERTIES(pbch_enodeb PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD") SET_TARGET_PROPERTIES(pdsch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD") SET_TARGET_PROPERTIES(pdsch_enodeb PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD") ELSE(${CUHD_FIND} EQUAL -1) - target_link_libraries(pbch_ue cuhd) - target_link_libraries(pbch_enodeb cuhd) target_link_libraries(pdsch_ue cuhd) target_link_libraries(pdsch_enodeb cuhd) ENDIF(${CUHD_FIND} EQUAL -1) IF(${GRAPHICS_FIND} EQUAL -1) - SET_TARGET_PROPERTIES(pbch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS") - SET_TARGET_PROPERTIES(pbch_enodeb PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS") SET_TARGET_PROPERTIES(pdsch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS") SET_TARGET_PROPERTIES(pdsch_enodeb PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS") ELSE(${GRAPHICS_FIND} EQUAL -1) - target_link_libraries(pbch_ue graphics) - target_link_libraries(pbch_enodeb graphics) target_link_libraries(pdsch_ue graphics) target_link_libraries(pdsch_enodeb graphics) ENDIF(${GRAPHICS_FIND} EQUAL -1) diff --git a/lte/phy/examples/pbch_enodeb.c b/lte/phy/examples/pbch_enodeb.c deleted file mode 100644 index 529addfa8..000000000 --- a/lte/phy/examples/pbch_enodeb.c +++ /dev/null @@ -1,293 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2014 The libLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the libLTE library. - * - * libLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * libLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * A copy of the GNU Lesser General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include -#include -#include -#include -#include - -#include "liblte/phy/phy.h" - -#ifndef DISABLE_UHD - #include "liblte/cuhd/cuhd.h" - void *uhd; -#endif - - -lte_cell_t cell = { - 6, // nof_prb - 1, // nof_ports - 1, // cell_id - CPNORM // cyclic prefix -}; - -char *output_file_name = NULL; -int nof_frames=-1; -char *uhd_args = ""; - -float uhd_amp=0.25, uhd_gain=10.0, uhd_freq=2400000000; - -filesink_t fsink; -lte_fft_t ifft; -pbch_t pbch; - -cf_t *sf_buffer = NULL, *output_buffer = NULL; -int sf_n_re, sf_n_samples; - -#define UHD_SAMP_FREQ 1920000 - -void usage(char *prog) { - printf("Usage: %s [agmfoncvp]\n", prog); -#ifndef DISABLE_UHD - printf("\t-a UHD args [Default %s]\n", uhd_args); - printf("\t-g UHD TX gain [Default %.2f dB]\n", uhd_gain); - printf("\t-m UHD signal amplitude [Default %.2f]\n", uhd_amp); - printf("\t-f UHD TX frequency [Default %.1f MHz]\n", uhd_freq/1000000); -#else - printf("\t UHD is disabled. CUHD library not available\n"); -#endif - printf("\t-o output_file [Default USRP]\n"); - printf("\t-n number of frames [Default %d]\n", nof_frames); - printf("\t-c cell id [Default %d]\n", cell.id); - printf("\t-p nof_prb [Default %d]\n", cell.nof_prb); - printf("\t-v [set verbose to debug, default none]\n"); -} - -void parse_args(int argc, char **argv) { - int opt; - while ((opt = getopt(argc, argv, "agfmoncpv")) != -1) { - switch(opt) { - case 'a': - uhd_args = argv[optind]; - break; - case 'g': - uhd_gain = atof(argv[optind]); - break; - case 'm': - uhd_amp = atof(argv[optind]); - break; - case 'f': - uhd_freq = atof(argv[optind]); - break; - case 'o': - output_file_name = argv[optind]; - break; - case 'n': - nof_frames = atoi(argv[optind]); - break; - case 'p': - cell.nof_prb = atoi(argv[optind]); - break; - case 'c': - cell.id = atoi(argv[optind]); - break; - case 'v': - verbose++; - break; - default: - usage(argv[0]); - exit(-1); - } - } -#ifdef DISABLE_UHD - if (!output_file_name) { - usage(argv[0]); - exit(-1); - } -#endif -} - -void base_init() { - /* init memory */ - sf_buffer = malloc(sizeof(cf_t) * sf_n_re); - if (!sf_buffer) { - perror("malloc"); - exit(-1); - } - output_buffer = malloc(sizeof(cf_t) * sf_n_samples); - if (!output_buffer) { - perror("malloc"); - exit(-1); - } - /* open file or USRP */ - if (output_file_name) { - if (filesink_init(&fsink, output_file_name, COMPLEX_FLOAT_BIN)) { - fprintf(stderr, "Error opening file %s\n", output_file_name); - exit(-1); - } - } else { -#ifndef DISABLE_UHD - printf("Opening UHD device...\n"); - if (cuhd_open(uhd_args,&uhd)) { - fprintf(stderr, "Error opening uhd\n"); - exit(-1); - } -#else - printf("Error UHD not available. Select an output file\n"); - exit(-1); -#endif - } - - /* create ifft object */ - if (lte_ifft_init(&ifft, CPNORM, cell.nof_prb)) { - fprintf(stderr, "Error creating iFFT object\n"); - exit(-1); - } - if (pbch_init(&pbch, cell)) { - fprintf(stderr, "Error creating PBCH object\n"); - exit(-1); - } -} - -void base_free() { - - pbch_free(&pbch); - - lte_ifft_free(&ifft); - - if (sf_buffer) { - free(sf_buffer); - } - if (output_buffer) { - free(output_buffer); - } - if (output_file_name) { - filesink_free(&fsink); - } else { -#ifndef DISABLE_UHD - cuhd_close(&uhd); -#endif - } -} - -int main(int argc, char **argv) { - int nf, sf_idx, N_id_2; - cf_t pss_signal[PSS_LEN]; - float sss_signal0[SSS_LEN]; // for subframe 0 - float sss_signal5[SSS_LEN]; // for subframe 5 - pbch_mib_t mib; - refsignal_t refs[NSLOTS_X_FRAME]; - int i, n; - cf_t *sf_symbols[MAX_PORTS]; - - -#ifdef DISABLE_UHD - if (argc < 3) { - usage(argv[0]); - exit(-1); - } -#endif - - parse_args(argc,argv); - - N_id_2 = cell.id%3; - sf_n_re = 2 * CPNORM_NSYMB * cell.nof_prb * RE_X_RB; - sf_n_samples = 2 * SLOT_LEN_CPNORM(lte_symbol_sz(cell.nof_prb)); - - /* this *must* be called after setting slot_len_* */ - base_init(); - - /* Generate PSS/SSS signals */ - pss_generate(pss_signal, N_id_2); - sss_generate(sss_signal0, sss_signal5, cell.id); - - /* Generate CRS signals */ - lte_cell_t cell; - cell.id = cell.id; - cell.nof_prb = 6; - cell.cp = CPNORM; - cell.nof_ports = 1; - - for (i=0;i -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "liblte/phy/phy.h" - -#ifndef DISABLE_UHD -#include "liblte/cuhd/cuhd.h" -void *uhd; -#endif - -#ifndef DISABLE_GRAPHICS -#include "liblte/graphics/plot.h" -plot_real_t poutfft; -plot_complex_t pce; -plot_scatter_t pscatrecv, pscatequal; -#endif - -#define MHZ 1000000 -#define SAMP_FREQ 1920000 -#define FLEN 9600 -#define FLEN_PERIOD 0.005 - -#define NOF_PORTS 2 - -float find_threshold = 9.0; -int max_track_lost = 20, nof_frames = -1; -int track_len = 300; -char *input_file_name = NULL; -int disable_plots = 0; - -int go_exit = 0; - -float uhd_freq = 2600000000.0, uhd_gain = 20.0; -char *uhd_args = ""; - -filesource_t fsrc; -cf_t *input_buffer, *fft_buffer, *ce[MAX_PORTS]; -pbch_t pbch; -lte_fft_t fft; -chest_t chest; -sync_t ssync; -cfo_t cfocorr; - -enum sync_state { - FIND, TRACK -}; - -void usage(char *prog) { - printf("Usage: %s [iagfndvt]\n", prog); - printf("\t-i input_file [Default use USRP]\n"); -#ifndef DISABLE_UHD - printf("\t-a UHD args [Default %s]\n", uhd_args); - printf("\t-g UHD RX gain [Default %.2f dB]\n", uhd_gain); - printf("\t-f UHD RX frequency [Default %.1f MHz]\n", uhd_freq / 1000000); -#else - printf("\t UHD is disabled. CUHD library not available\n"); -#endif - - printf("\t-n nof_frames [Default %d]\n", nof_frames); - printf("\t-t PSS threshold [Default %f]\n", find_threshold); -#ifndef DISABLE_GRAPHICS - printf("\t-d disable plots [Default enabled]\n"); -#else - printf("\t plots are disabled. Graphics library not available\n"); -#endif - printf("\t-v [set verbose to debug, default none]\n"); -} - -void parse_args(int argc, char **argv) { - int opt; - while ((opt = getopt(argc, argv, "iagfndvt")) != -1) { - switch (opt) { - case 'i': - input_file_name = argv[optind]; - break; - case 'a': - uhd_args = argv[optind]; - break; - case 'g': - uhd_gain = atof(argv[optind]); - break; - case 'f': - uhd_freq = atof(argv[optind]); - break; - case 't': - find_threshold = atof(argv[optind]); - break; - case 'n': - nof_frames = atoi(argv[optind]); - break; - case 'd': - disable_plots = 1; - break; - case 'v': - verbose++; - break; - default: - usage(argv[0]); - exit(-1); - } - } -} - -#ifndef DISABLE_GRAPHICS - -void init_plots() { - plot_init(); - plot_real_init(&poutfft); - plot_real_setTitle(&poutfft, "Output FFT - Magnitude"); - plot_real_setLabels(&poutfft, "Index", "dB"); - plot_real_setYAxisScale(&poutfft, -60, 0); - plot_real_setXAxisScale(&poutfft, 1, 504); - - plot_complex_init(&pce); - plot_complex_setTitle(&pce, "Channel Estimates"); - plot_complex_setYAxisScale(&pce, Ip, -0.01, 0.01); - plot_complex_setYAxisScale(&pce, Q, -0.01, 0.01); - plot_complex_setYAxisScale(&pce, Magnitude, 0, 0.01); - plot_complex_setYAxisScale(&pce, Phase, -M_PI, M_PI); - - plot_scatter_init(&pscatrecv); - plot_scatter_setTitle(&pscatrecv, "Received Symbols"); - plot_scatter_setXAxisScale(&pscatrecv, -0.01, 0.01); - plot_scatter_setYAxisScale(&pscatrecv, -0.01, 0.01); - - plot_scatter_init(&pscatequal); - plot_scatter_setTitle(&pscatequal, "Equalized Symbols"); - plot_scatter_setXAxisScale(&pscatequal, -1, 1); - plot_scatter_setYAxisScale(&pscatequal, -1, 1); -} - -#endif - -int base_init(int frame_length) { - int i; - -#ifndef DISABLE_GRAPHICS - if (!disable_plots) { - init_plots(); - } -#else - printf("-- PLOTS are disabled. Graphics library not available --\n\n"); -#endif - - if (input_file_name) { - if (filesource_init(&fsrc, input_file_name, COMPLEX_FLOAT_BIN)) { - return -1; - } - } else { - /* open UHD device */ -#ifndef DISABLE_UHD - printf("Opening UHD device...\n"); - if (cuhd_open(uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); - return -1; - } -#else - printf("Error UHD not available. Select an input file\n"); - return -1; -#endif - } - - input_buffer = (cf_t*) malloc(frame_length * sizeof(cf_t)); - if (!input_buffer) { - perror("malloc"); - return -1; - } - - fft_buffer = (cf_t*) malloc(CPNORM_NSYMB * 72 * sizeof(cf_t)); - if (!fft_buffer) { - perror("malloc"); - return -1; - } - for (i = 0; i < MAX_PORTS; i++) { - ce[i] = (cf_t*) malloc(CPNORM_NSYMB * 72 * sizeof(cf_t)); - if (!ce[i]) { - perror("malloc"); - return -1; - } - } - if (sync_init(&ssync, FLEN)) { - fprintf(stderr, "Error initiating PSS/SSS\n"); - return -1; - } - if (chest_init(&chest, LINEAR, CPNORM, 6, NOF_PORTS)) { - fprintf(stderr, "Error initializing equalizer\n"); - return -1; - } - - if (cfo_init(&cfocorr, FLEN)) { - fprintf(stderr, "Error initiating CFO\n"); - return -1; - } - if (lte_fft_init(&fft, CPNORM, 6)) { - fprintf(stderr, "Error initializing FFT\n"); - return -1; - } - - return 0; -} - -void base_free() { - int i; - - if (input_file_name) { - filesource_free(&fsrc); - } else { -#ifndef DISABLE_UHD - cuhd_close(uhd); -#endif - } - -#ifndef DISABLE_GRAPHICS - plot_exit(); -#endif - - sync_free(&ssync); - lte_fft_free(&fft); - chest_free(&chest); - cfo_free(&cfocorr); - - free(input_buffer); - free(fft_buffer); - for (i = 0; i < MAX_PORTS; i++) { - free(ce[i]); - } -} - -int mib_decoder_init(int cell_id) { - - lte_cell_t cell; - - cell.id = cell_id; - cell.nof_ports = MAX_PORTS; - cell.nof_prb = 6; - cell.cp = CPNORM; - - if (chest_ref_LTEDL(&chest, cell)) { - fprintf(stderr, "Error initializing reference signal\n"); - return -1; - } - - if (pbch_init(&pbch, cell)) { - fprintf(stderr, "Error initiating PBCH\n"); - return -1; - } - DEBUG("PBCH initiated cell_id=%d\n", cell.id); - return 0; -} - -int mib_decoder_run(cf_t *input, pbch_mib_t *mib) { - int i, n; - lte_fft_run_slot(&fft, input, fft_buffer); - - /* Get channel estimates for each port */ - for (i = 0; i < NOF_PORTS; i++) { - chest_ce_slot_port(&chest, fft_buffer, ce[i], 1, i); - } - - DEBUG("Decoding PBCH\n", 0); - n = pbch_decode(&pbch, fft_buffer, ce, mib); - -#ifndef DISABLE_GRAPHICS - float tmp[72 * 7]; - if (!disable_plots) { - for (i = 0; i < 72 * 7; i++) { - tmp[i] = 10 * log10f(cabsf(fft_buffer[i])); - if (isinf(tmp[i])) { - tmp[i] = -80; - } - } - - plot_real_setNewData(&poutfft, tmp, 72 * 7); - plot_complex_setNewData(&pce, ce[0], 72 * 7); - plot_scatter_setNewData(&pscatrecv, pbch.pbch_symbols[0], pbch.nof_symbols); - if (n) { - plot_scatter_setNewData(&pscatequal, pbch.pbch_d, pbch.nof_symbols); - } - } -#endif - - return n; -} - -void sigintHandler(int sig_num) { - go_exit = 1; -} - -int main(int argc, char **argv) { - int frame_cnt; - int cell_id; - int find_idx, track_idx, last_found; - enum sync_state state; - int nslot; - pbch_mib_t mib; - float cfo; - int n; - int nof_found_mib = 0; - float timeoffset = 0; - -#ifdef DISABLE_UHD - if (argc < 3) { - usage(argv[0]); - exit(-1); - } -#endif - - parse_args(argc, argv); - - if (base_init(FLEN)) { - fprintf(stderr, "Error initializing memory\n"); - exit(-1); - } - - sync_pss_det_peak_to_avg(&ssync); - - if (!input_file_name) { -#ifndef DISABLE_UHD - INFO("Setting sampling frequency %.2f MHz\n", (float) SAMP_FREQ/MHZ); - cuhd_set_rx_srate(uhd, SAMP_FREQ); - cuhd_set_rx_gain(uhd, uhd_gain); - /* set uhd_freq */ - cuhd_set_rx_freq(uhd, (double) uhd_freq); - cuhd_rx_wait_lo_locked(uhd); - DEBUG("Set uhd_freq to %.3f MHz\n", (double ) uhd_freq); - - DEBUG("Starting receiver...\n", 0); - cuhd_start_rx_stream(uhd); -#endif - } - - printf("\n --- Press Ctrl+C to exit --- \n"); - signal(SIGINT, sigintHandler); - - state = FIND; - nslot = 0; - find_idx = 0; - cfo = 0; - mib.sfn = -1; - frame_cnt = 0; - last_found = 0; - sync_set_threshold(&ssync, find_threshold); - - while (!go_exit && (frame_cnt < nof_frames || nof_frames == -1)) { - INFO(" ----- RECEIVING %d SAMPLES ---- \n", FLEN); - if (input_file_name) { - n = filesource_read(&fsrc, input_buffer, FLEN); - if (n == -1) { - fprintf(stderr, "Error reading file\n"); - exit(-1); - } else if (n < FLEN) { - filesource_seek(&fsrc, 0); - filesource_read(&fsrc, input_buffer, FLEN); - } - } else { -#ifndef DISABLE_UHD - cuhd_recv(uhd, input_buffer, FLEN, 1); -#endif - } - - switch (state) { - case FIND: - /* find peak in all frame */ - find_idx = sync_find(&ssync, input_buffer); - INFO("FIND %3d:\tPAR=%.2f\n", frame_cnt, sync_get_peak_to_avg(&ssync)); - if (find_idx != -1) { - /* if found peak, go to track and set track threshold */ - cell_id = sync_get_cell_id(&ssync); - if (cell_id != -1) { - frame_cnt = -1; - last_found = 0; - mib_decoder_init(cell_id); - nof_found_mib = 0; - nslot = sync_get_slot_id(&ssync); - nslot = (nslot + 10) % 20; - cfo = 0; - timeoffset = 0; - printf("\n"); - state = TRACK; - } else { - printf("cellid=-1\n"); - } - } - if (verbose == VERBOSE_NONE) { - printf("Finding PSS... PAR=%.2f\r", sync_get_peak_to_avg(&ssync)); - } - break; - case TRACK: - /* Find peak around known position find_idx */ - INFO("TRACK %3d: PSS find_idx %d offset %d\n", frame_cnt, find_idx, - find_idx - track_len); - track_idx = sync_track(&ssync, &input_buffer[find_idx - track_len]); - - if (track_idx != -1) { - /* compute cumulative moving average CFO */ - cfo = (sync_get_cfo(&ssync) + frame_cnt * cfo) / (frame_cnt + 1); - /* compute cumulative moving average time offset */ - timeoffset = (float) (track_idx - track_len + timeoffset * frame_cnt) - / (frame_cnt + 1); - last_found = frame_cnt; - find_idx = (find_idx + track_idx - track_len) % FLEN; - } else { - /* if sync not found, adjust time offset with the averaged value */ - find_idx = (find_idx + (int) timeoffset) % FLEN; - } - - /* if we missed too many PSS go back to FIND */ - if (frame_cnt - last_found > max_track_lost) { - INFO("%d frames lost. Going back to FIND", frame_cnt - last_found); - printf("\r\n"); - fflush(stdout); - printf("\r\n"); - state = FIND; - } - - // Correct CFO - INFO("Correcting CFO=%.4f\n", cfo); - - cfo_correct(&cfocorr, input_buffer, -cfo / 128); - - if (nslot == 0 && find_idx + 960 < FLEN) { - INFO("Finding MIB at idx %d\n", find_idx); - if (mib_decoder_run(&input_buffer[find_idx], &mib)) { - INFO("MIB detected attempt=%d\n", frame_cnt); - if (verbose == VERBOSE_NONE) { - if (!nof_found_mib) { - printf("\r\n"); - fflush(stdout); - printf("\r\n"); - printf(" - Phy. CellId:\t%d\n", cell_id); - pbch_mib_fprint(stdout, &mib); - } - } - nof_found_mib++; - } else { - INFO("MIB not found attempt %d\n", frame_cnt); - } - if (frame_cnt) { - printf( - "SFN: %4d, CFO: %+.4f KHz, SFO: %+.4f Khz, TimeOffset: %4d, Errors: %4d/%4d, ErrorRate: %.1e\r", - mib.sfn, cfo * 15, timeoffset / 5, find_idx, - frame_cnt - 2 * (nof_found_mib - 1), frame_cnt, - (float) (frame_cnt - 2 * (nof_found_mib - 1)) / frame_cnt); - fflush(stdout); - } - } - if (input_file_name) { - usleep(5000); - } - nslot = (nslot + 10) % 20; - break; - } - frame_cnt++; - } - - base_free(); - - printf("\nBye\n"); - exit(0); -} - diff --git a/lte/phy/examples/pdsch_ue.c b/lte/phy/examples/pdsch_ue.c index ff6995e0e..89600c686 100644 --- a/lte/phy/examples/pdsch_ue.c +++ b/lte/phy/examples/pdsch_ue.c @@ -57,7 +57,7 @@ plot_scatter_t pscatrecv, pscatequal; float find_threshold = 9.0; int nof_frames = -1; -int pdsch_errors = 0, pdsch_total = 0; +int pkt_errors = 0, pkts_total = 0; int frame_cnt; char *input_file_name = NULL; int disable_plots = 0; @@ -71,7 +71,9 @@ int sf_n_samples; lte_cell_t cell; int cell_id_initated = 0, mib_initiated = 0; -int subframe_number; +int frame_number; + +bool pbch_only = false; int go_exit = 0; @@ -96,7 +98,7 @@ sync_frame_t sframe; #define DOWNSAMPLE_FACTOR(x, y) lte_symbol_sz(x) / lte_symbol_sz(y) void usage(char *prog) { - printf("Usage: %s [iagfndvtp]\n", prog); + printf("Usage: %s [iagfndvtpb]\n", prog); printf("\t-i input_file [Default use USRP]\n"); #ifndef DISABLE_UHD printf("\t-a UHD args [Default %s]\n", uhd_args); @@ -105,6 +107,7 @@ void usage(char *prog) { #else printf("\t UHD is disabled. CUHD library not available\n"); #endif + printf("\t-b Decode PBCH only [Default All]\n"); printf("\t-p sampling_nof_prb [Default %d]\n", sampling_nof_prb); printf("\t-n nof_frames [Default %d]\n", nof_frames); printf("\t-t PSS threshold [Default %f]\n", find_threshold); @@ -118,7 +121,7 @@ void usage(char *prog) { void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "iagfndvtp")) != -1) { + while ((opt = getopt(argc, argv, "iagfndvtpb")) != -1) { switch (opt) { case 'i': input_file_name = argv[optind]; @@ -132,6 +135,9 @@ void parse_args(int argc, char **argv) { case 'f': uhd_freq = atof(argv[optind]); break; + case 'b': + pbch_only = true; + break; case 't': find_threshold = atof(argv[optind]); break; @@ -230,13 +236,13 @@ int base_init(int nof_prb) { perror("malloc"); return -1; } + input_decim_buffer = (cf_t*) malloc(sf_n_samples * sizeof(cf_t)); if (!input_decim_buffer) { perror("malloc"); return -1; } - /* This buffer is the aligned version of input_buffer */ sf_buffer = (cf_t*) malloc(sf_n_samples * sizeof(cf_t)); if (!sf_buffer) { @@ -438,7 +444,7 @@ int rx_run(cf_t *input, int sf_idx) { fprintf(stderr, "Can't unpack PDSCH message\n"); break; } - if (VERBOSE_ISINFO() || !pdsch_total) { + if (VERBOSE_ISINFO() || !pkts_total) { printf("\n"); ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb); printf("\n"); @@ -451,9 +457,9 @@ int rx_run(cf_t *input, int sf_idx) { cell.nof_prb<10?(cfi+1):cfi, CPNORM); if (pdsch_decode(&pdsch, fft_buffer, ce, data, sf_idx, ra_dl.mcs, &prb_alloc)) { - pdsch_errors++; + pkt_errors++; } - pdsch_total++; + pkts_total++; break; default: fprintf(stderr, "Unsupported message type\n"); @@ -497,7 +503,7 @@ int run_receiver(cf_t *input, int cell_id, int sf_idx) { if (!cell_id_initated) { cell_id_init(sampling_nof_prb, cell_id); } - if (!cell.nof_prb) { + if (!cell.nof_prb || pbch_only) { if (!sf_idx) { if (mib_decoder_run(input, &mib)) { @@ -506,7 +512,7 @@ int run_receiver(cf_t *input, int cell_id, int sf_idx) { cell.cp = CPNORM; cell.nof_ports = mib.nof_ports; cell.nof_prb = mib.nof_prb; - subframe_number = mib.sfn; + frame_number = mib.sfn; if (!mib_initiated) { if (mib_init(mib.phich_resources, mib.phich_length)) { @@ -518,10 +524,31 @@ int run_receiver(cf_t *input, int cell_id, int sf_idx) { printf(" - Phy. CellId:\t %d\n", cell_id); pbch_mib_fprint(stdout, &mib); } + } else if (pbch_only) { + pkt_errors++; + } + if (pbch_only) { + #ifndef DISABLE_GRAPHICS + if (!disable_plots) { + int i; + int n_re = 2 * RE_X_RB * CPNORM_NSYMB * sampling_nof_prb; + for (i = 0; i < n_re; i++) { + tmp_plot[i] = 10 * log10f(cabsf(fft_buffer[i])); + if (isinf(tmp_plot[i])) { + tmp_plot[i] = -80; + } + } + plot_real_setNewData(&poutfft, tmp_plot, n_re); + plot_complex_setNewData(&pce, ce[0], n_re); + plot_scatter_setNewData(&pscatrecv, pbch.pbch_symbols[0], pbch.nof_symbols); + plot_scatter_setNewData(&pscatequal, pbch.pbch_d, pbch.nof_symbols); + } + #endif + pkts_total++; } } } - if (cell.nof_prb) { + if (cell.nof_prb && !pbch_only) { if (rx_run(input, sf_idx)) { return -1; } @@ -597,11 +624,12 @@ int main(int argc, char **argv) { } printf("\n --- Press Ctrl+C to exit --- \n"); + signal(SIGINT, sigintHandler); /* Initialize variables */ frame_cnt = 0; - subframe_number = -1; + frame_number = -1; /* The number of samples read from the USRP or file corresponds to 1 ms (subframe) */ sf_n_samples = 1920 * lte_symbol_sz(sampling_nof_prb)/128; @@ -617,19 +645,23 @@ int main(int argc, char **argv) { /* not yet synched */ break; case 1: + /* sf_buffer is aligned to the subframe */ + if (!(frame_cnt%10)) { - subframe_number++; + frame_number++; } + /* synch'd and tracking */ if (run_receiver(sf_buffer, sync_frame_cell_id(&sframe), sync_frame_sfidx(&sframe))) { exit(-1); } + if (!(frame_cnt % 10)) { printf( "SFN: %4d, CFO: %+.4f KHz, SFO: %+.4f Khz, TimeOffset: %4d, Errors: %4d/%4d, BLER: %.1e\r", - subframe_number, sframe.cur_cfo * 15, sframe.timeoffset / 5, sframe.peak_idx, - pdsch_errors, pdsch_total, - (float) pdsch_errors / pdsch_total); + frame_number, sframe.cur_cfo * 15, sframe.timeoffset / 5, sframe.peak_idx, + pkt_errors, pkts_total, + (float) pkt_errors / pkts_total); fflush(stdout); }