Removed PBCH eNodeB/UE examples and integrated into PDSCH ones using the program argument -b

This commit is contained in:
ismagom 2014-06-30 01:32:42 +02:00
parent 231c29ef21
commit 67fb600193
4 changed files with 48 additions and 819 deletions

View File

@ -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)

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#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<NSLOTS_X_FRAME;i++) {
if (refsignal_init_LTEDL(&refs[i], 0, i, cell)) {
fprintf(stderr, "Error initiating CRS slot=%d\n", i);
return -1;
}
}
mib.nof_ports = cell.nof_ports;
mib.nof_prb = cell.nof_prb;
mib.phich_length = PHICH_NORM;
mib.phich_resources = R_1;
mib.sfn = 0;
for (i=0;i<MAX_PORTS;i++) { // now there's only 1 port
sf_symbols[i] = sf_buffer;
}
#ifndef DISABLE_UHD
if (!output_file_name) {
printf("Set TX rate: %.2f MHz\n", cuhd_set_tx_srate(uhd, UHD_SAMP_FREQ)/1000000);
printf("Set TX gain: %.1f dB\n", cuhd_set_tx_gain(uhd, uhd_gain));
printf("Set TX freq: %.2f MHz\n", cuhd_set_tx_freq(uhd, uhd_freq)/1000000);
}
#endif
nf = 0;
while(nf<nof_frames || nof_frames == -1) {
for (sf_idx=0;sf_idx<NSUBFRAMES_X_FRAME;sf_idx++) {
bzero(sf_buffer, sizeof(cf_t) * sf_n_re);
if (sf_idx == 0 || sf_idx == 5) {
pss_put_slot(pss_signal, sf_buffer, cell.nof_prb, CPNORM);
sss_put_slot(sf_idx?sss_signal5:sss_signal0, sf_buffer, cell.nof_prb, CPNORM);
}
if (sf_idx == 0) {
pbch_encode(&pbch, &mib, sf_symbols);
}
for (n=0;n<2;n++) {
refsignal_put(&refs[2*sf_idx+n], &sf_buffer[n*sf_n_re/2]);
}
/* Transform to OFDM symbols */
lte_ifft_run_sf(&ifft, sf_buffer, output_buffer);
/* send to file or usrp */
if (output_file_name) {
filesink_write(&fsink, output_buffer, sf_n_samples);
usleep(5000);
} else {
#ifndef DISABLE_UHD
vec_sc_prod_cfc(output_buffer, uhd_amp, output_buffer, sf_n_samples);
cuhd_send(uhd, output_buffer, sf_n_samples, 1);
#endif
}
}
mib.sfn=(mib.sfn+1)%1024;
printf("SFN: %4d\r", mib.sfn);fflush(stdout);
nf++;
}
base_free();
printf("Done\n");
exit(0);
}

View File

@ -1,496 +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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
#include <assert.h>
#include <signal.h>
#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);
}

View File

@ -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);
}