File read in pdsch_ue

master
ismagom 10 years ago
parent 359b8dcd72
commit 5c8a94ddfc

@ -51,14 +51,19 @@ LIST(FIND OPTIONAL_LIBS graphics GRAPHICS_FIND)
# These two can be compiled without UHD or graphics support
#################################################################
IF(${CUHD_FIND} GREATER -1)
add_executable(pdsch_ue pdsch_ue.c cuhd_utils.c)
target_link_libraries(pdsch_ue lte_rrc lte_phy cuhd)
target_link_libraries(pdsch_ue lte_rrc lte_phy)
add_executable(pdsch_enodeb pdsch_enodeb.c)
target_link_libraries(pdsch_enodeb lte_rrc lte_phy cuhd)
target_link_libraries(pdsch_enodeb lte_rrc lte_phy)
IF(${CUHD_FIND} EQUAL -1)
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(pdsch_ue cuhd)
target_link_libraries(pdsch_enodeb cuhd)
ENDIF(${CUHD_FIND} EQUAL -1)
IF(${GRAPHICS_FIND} EQUAL -1)
SET_TARGET_PROPERTIES(pdsch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS")
@ -68,9 +73,6 @@ IF(${CUHD_FIND} GREATER -1)
target_link_libraries(pdsch_enodeb graphics)
ENDIF(${GRAPHICS_FIND} EQUAL -1)
ENDIF(${CUHD_FIND} GREATER -1)
#################################################################
# These examples need the UHD driver

@ -38,9 +38,13 @@
#include "liblte/rrc/rrc.h"
#include "liblte/phy/phy.h"
#include "liblte/graphics/plot/plot_waterfall.h"
#ifndef DISABLE_UHD
#include "liblte/cuhd/cuhd.h"
#include "cuhd_utils.h"
#include "liblte/graphics/plot/plot_waterfall.h"
#endif
#define STDOUT_COMPACT
@ -70,6 +74,8 @@ typedef struct {
bool disable_plots;
int force_N_id_2;
uint16_t rnti;
char *input_file_name;
uint32_t file_nof_prb;
char *uhd_args;
float uhd_freq;
float uhd_gain;
@ -83,6 +89,8 @@ void args_default(prog_args_t *args) {
args->nof_subframes = -1;
args->rnti = SIRNTI;
args->force_N_id_2 = -1; // Pick the best
args->input_file_name = NULL;
args->file_nof_prb = 6;
args->uhd_args = "";
args->uhd_freq = -1.0;
args->uhd_gain = 60.0;
@ -93,9 +101,15 @@ void args_default(prog_args_t *args) {
}
void usage(prog_args_t *args, char *prog) {
printf("Usage: %s [agldnruv] -f rx_frequency (in Hz)\n", prog);
printf("Usage: %s [agildnruv] -f rx_frequency (in Hz) | -i input_file\n", prog);
#ifndef DISABLE_GRAPHICS
printf("\t-a UHD args [Default %s]\n", args->uhd_args);
printf("\t-g UHD RX gain [Default %.2f dB]\n", args->uhd_gain);
#else
printf("\t UHD is disabled. CUHD library not available\n");
#endif
printf("\t-i input_file [Default USRP]\n");
printf("\t-p nof_prb for input file [Default %d]\n", args->file_nof_prb);
printf("\t-r RNTI [Default 0x%x]\n",args->rnti);
printf("\t-l Force N_id_2 [Default best]\n");
#ifndef DISABLE_GRAPHICS
@ -114,8 +128,14 @@ void usage(prog_args_t *args, char *prog) {
void parse_args(prog_args_t *args, int argc, char **argv) {
int opt;
args_default(args);
while ((opt = getopt(argc, argv, "agldnvrfuUsS")) != -1) {
while ((opt = getopt(argc, argv, "aglipdnvrfuUsS")) != -1) {
switch (opt) {
case 'i':
args->input_file_name = argv[optind];
break;
case 'p':
args->file_nof_prb = atoi(argv[optind]);
break;
case 'a':
args->uhd_args = argv[optind];
break;
@ -157,7 +177,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
exit(-1);
}
}
if (args->uhd_freq < 0) {
if (args->uhd_freq < 0 && args->input_file_name == NULL) {
usage(args, argv[0]);
exit(-1);
}
@ -176,10 +196,12 @@ void sig_int_handler(int signo)
}
}
#ifndef DISABLE_UHD
int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples) {
DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return cuhd_recv(h, data, nsamples, 1);
}
#endif
extern float mean_exec_time;
@ -217,6 +239,9 @@ int main(int argc, char **argv) {
exit(-1);
}
}
#ifndef DISABLE_UHD
if (!prog_args.input_file_name) {
printf("Opening UHD device...\n");
if (cuhd_open(prog_args.uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
@ -252,18 +277,41 @@ int main(int argc, char **argv) {
cuhd_stop_rx_stream(uhd);
cuhd_flush_buffer(uhd);
if (ue_mib_init(&ue_mib, cell)) {
fprintf(stderr, "Error initaiting UE MIB decoder\n");
exit(-1);
}
}
#endif
/* If reading from file, go straight to PDSCH decoding. Otherwise, decode MIB first */
if (prog_args.input_file_name) {
state = DECODE_PDSCH;
/* preset cell configuration */
cell.id = 1;
cell.cp = CPNORM;
cell.phich_length = PHICH_NORM;
cell.phich_resources = R_1;
cell.nof_ports = 1;
cell.nof_prb = prog_args.file_nof_prb;
if (ue_sync_init_file(&ue_sync, prog_args.file_nof_prb, prog_args.input_file_name)) {
fprintf(stderr, "Error initiating ue_sync\n");
exit(-1);
}
} else {
state = DECODE_MIB;
if (ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper, uhd)) {
fprintf(stderr, "Error initiating ue_sync\n");
exit(-1);
}
}
if (ue_dl_init(&ue_dl, cell, prog_args.rnti==SIRNTI?1:prog_args.rnti)) { // This is the User RNTI
fprintf(stderr, "Error initiating UE downlink processing module\n");
exit(-1);
}
if (ue_mib_init(&ue_mib, cell)) {
fprintf(stderr, "Error initaiting UE MIB decoder\n");
exit(-1);
}
/* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */
ue_dl_set_rnti(&ue_dl, prog_args.rnti);
@ -280,7 +328,11 @@ int main(int argc, char **argv) {
}
#endif
#ifndef DISABLE_UHD
if (!prog_args.input_file_name) {
cuhd_start_rx_stream(uhd);
}
#endif
// Variables for measurements
uint32_t nframes=0;
@ -389,7 +441,7 @@ int main(int argc, char **argv) {
}
#ifndef DISABLE_GRAPHICS
if (!prog_args.disable_plots) {
do_plots(&ue_dl, ue_sync_get_sfidx(&ue_sync), &ue_sync);
do_plots(&ue_dl, ue_sync_get_sfidx(&ue_sync), !prog_args.input_file_name?&ue_sync:NULL);
}
#endif
} else if (ret == 0) {
@ -402,9 +454,14 @@ int main(int argc, char **argv) {
} // Main loop
ue_dl_free(&ue_dl);
ue_mib_free(&ue_mib);
ue_sync_free(&ue_sync);
#ifndef DISABLE_UHD
if (!prog_args.input_file_name) {
ue_mib_free(&ue_mib);
cuhd_close(uhd);
}
#endif
printf("\nBye\n");
exit(0);
}
@ -479,6 +536,7 @@ void do_plots(ue_dl_t *q, uint32_t sf_idx, ue_sync_t *qs) {
plot_waterfall_appendNewData(&poutfft, &tmp_plot[i*RE_X_RB*q->cell.nof_prb], RE_X_RB*q->cell.nof_prb);
}
plot_real_setNewData(&pce, tmp_plot2, REFSIGNAL_NUM_SF(q->cell.nof_prb,0));
if (qs) {
int max = vec_max_fi(qs->strack.pss.conv_output_avg, qs->strack.pss.frame_size+qs->strack.pss.fft_size-1);
vec_sc_prod_fff(qs->strack.pss.conv_output_avg,
1/qs->strack.pss.conv_output_avg[max],
@ -486,6 +544,8 @@ void do_plots(ue_dl_t *q, uint32_t sf_idx, ue_sync_t *qs) {
qs->strack.pss.frame_size+qs->strack.pss.fft_size-1);
plot_real_setNewData(&p_sync, tmp_plot2, qs->strack.pss.frame_size);
}
plot_scatter_setNewData(&pscatequal, q->pdsch.pdsch_d, nof_symbols);
plot_scatter_setNewData(&pscatequal_pdcch, q->pdcch.pdcch_d, 36*q->pdcch.nof_cce);
}

@ -36,6 +36,7 @@
#include "liblte/phy/ch_estimation/chest_dl.h"
#include "liblte/phy/phch/pbch.h"
#include "liblte/phy/common/fft.h"
#include "liblte/phy/io/filesource.h"
/**************************************************************
*
@ -46,6 +47,9 @@
* should be called regularly, returning every 1 ms. It reads from the
* USRP, aligns the samples to the subframe and performs time/freq synch.
*
* It is also possible to read the signal from a file using the init function
* ue_sync_init_file(). The sampling frequency is derived from the number of PRB.
*
* The function returns 1 when the signal is correctly acquired and the
* returned buffer is aligned with the subframe.
*
@ -62,6 +66,9 @@ typedef struct LIBLTE_API {
void *stream;
int (*recv_callback)(void*, void*, uint32_t);
filesource_t file_source;
bool file_mode;
ue_sync_state_t state;
cf_t *input_buffer;
@ -101,6 +108,10 @@ LIBLTE_API int ue_sync_init(ue_sync_t *q,
int (recv_callback)(void*, void*, uint32_t),
void *stream_handler);
LIBLTE_API int ue_sync_init_file(ue_sync_t *q,
uint32_t nof_prb,
char *file_name);
LIBLTE_API void ue_sync_free(ue_sync_t *q);
LIBLTE_API uint32_t ue_sync_sf_len(ue_sync_t *q);

@ -207,7 +207,6 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
int r = pdsch_decode(&pdsch, input_fft, ce, noise_power, data, sf_idx, &harq_process, rv);
tbs_is_zero:
if (nlhs >= 1) {
plhs[0] = mxCreateLogicalScalar(r == 0);
}

@ -34,9 +34,11 @@
#include "liblte/phy/ue/ue_sync.h"
#include "liblte/phy/io/filesource.h"
#include "liblte/phy/utils/debug.h"
#include "liblte/phy/utils/vector.h"
#define MAX_TIME_OFFSET 128
cf_t dummy[MAX_TIME_OFFSET];
@ -44,6 +46,40 @@ cf_t dummy[MAX_TIME_OFFSET];
#define TRACK_FRAME_SIZE 32
#define FIND_NOF_AVG_FRAMES 2
int ue_sync_init_file(ue_sync_t *q, uint32_t nof_prb, char *file_name) {
int ret = LIBLTE_ERROR_INVALID_INPUTS;
if (q != NULL &&
file_name != NULL &&
lte_nofprb_isvalid(nof_prb))
{
ret = LIBLTE_ERROR;
bzero(q, sizeof(ue_sync_t));
q->file_mode = true;
q->sf_len = SF_LEN(lte_symbol_sz(nof_prb));
if (filesource_init(&q->file_source, file_name, COMPLEX_FLOAT_BIN)) {
fprintf(stderr, "Error opening file %s\n", file_name);
goto clean_exit;
}
q->input_buffer = vec_malloc(q->sf_len * sizeof(cf_t));
if (!q->input_buffer) {
perror("malloc");
goto clean_exit;
}
ue_sync_reset(q);
ret = LIBLTE_SUCCESS;
}
clean_exit:
if (ret == LIBLTE_ERROR) {
ue_sync_free(q);
}
return ret;
}
int ue_sync_init(ue_sync_t *q,
lte_cell_t cell,
int (recv_callback)(void*, void*, uint32_t),
@ -65,6 +101,7 @@ int ue_sync_init(ue_sync_t *q,
q->cell = cell;
q->fft_size = lte_symbol_sz(q->cell.nof_prb);
q->sf_len = SF_LEN(q->fft_size);
q->file_mode = false;
if (cell.id == 1000) {
/* If the cell is unkown, decode SSS on track state */
@ -155,9 +192,12 @@ void ue_sync_free(ue_sync_t *q) {
if (q->input_buffer) {
free(q->input_buffer);
}
if (!q->file_mode) {
sync_free(&q->sfind);
sync_free(&q->strack);
} else {
filesource_free(&q->file_source);
}
bzero(q, sizeof(ue_sync_t));
}
@ -185,10 +225,12 @@ void ue_sync_decode_sss_on_track(ue_sync_t *q, bool enabled) {
}
void ue_sync_set_N_id_2(ue_sync_t *q, uint32_t N_id_2) {
if (!q->file_mode) {
ue_sync_reset(q);
sync_set_N_id_2(&q->strack, N_id_2);
sync_set_N_id_2(&q->sfind, N_id_2);
}
}
static int find_peak_ok(ue_sync_t *q) {
@ -229,7 +271,7 @@ static int find_peak_ok(ue_sync_t *q) {
return 0;
}
int track_peak_ok(ue_sync_t *q, uint32_t track_idx) {
static int track_peak_ok(ue_sync_t *q, uint32_t track_idx) {
/* Make sure subframe idx is what we expect */
if ((q->sf_idx != sync_get_sf_idx(&q->strack)) && q->decode_sss_on_track) {
@ -269,7 +311,7 @@ int track_peak_ok(ue_sync_t *q, uint32_t track_idx) {
return 1;
}
int track_peak_no(ue_sync_t *q) {
static int track_peak_no(ue_sync_t *q) {
/* if we missed too many PSS go back to FIND */
q->frame_no_cnt++;
@ -316,9 +358,33 @@ int ue_sync_get_buffer(ue_sync_t *q, cf_t **sf_symbols) {
q->input_buffer != NULL)
{
if (q->file_mode) {
usleep(1000);
int n = filesource_read(&q->file_source, q->input_buffer, q->sf_len);
if (n < 0) {
fprintf(stderr, "Error reading input file\n");
return LIBLTE_ERROR;
}
if (n == 0) {
filesource_seek(&q->file_source, 0);
q->sf_idx = 9;
int n = filesource_read(&q->file_source, q->input_buffer, q->sf_len);
if (n < 0) {
fprintf(stderr, "Error reading input file\n");
return LIBLTE_ERROR;
}
}
q->sf_idx++;
if (q->sf_idx == 10) {
q->sf_idx = 0;
}
INFO("Reading %d samples. sf_idx = %d\n", q->sf_len, q->sf_idx);
ret = 1;
*sf_symbols = q->input_buffer;
} else {
if (receive_samples(q)) {
fprintf(stderr, "Error receiving samples\n");
return -1;
return LIBLTE_ERROR;
}
switch (q->state) {
@ -390,13 +456,20 @@ int ue_sync_get_buffer(ue_sync_t *q, cf_t **sf_symbols) {
break;
}
}
}
return ret;
}
void ue_sync_reset(ue_sync_t *q) {
q->state = SF_FIND;
if (!q->file_mode) {
sync_reset(&q->strack);
} else {
q->sf_idx = 9;
}
q->state = SF_FIND;
q->frame_ok_cnt = 0;
q->frame_no_cnt = 0;
q->frame_total_cnt = 0;

Loading…
Cancel
Save