File read in pdsch_ue

master
ismagom 10 years ago
parent 359b8dcd72
commit 5c8a94ddfc

@ -51,25 +51,27 @@ LIST(FIND OPTIONAL_LIBS graphics GRAPHICS_FIND)
# These two can be compiled without UHD or graphics support # These two can be compiled without UHD or graphics support
################################################################# #################################################################
add_executable(pdsch_ue pdsch_ue.c cuhd_utils.c)
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)
IF(${CUHD_FIND} GREATER -1) IF(${CUHD_FIND} EQUAL -1)
add_executable(pdsch_ue pdsch_ue.c cuhd_utils.c) SET_TARGET_PROPERTIES(pdsch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD")
target_link_libraries(pdsch_ue lte_rrc lte_phy cuhd) SET_TARGET_PROPERTIES(pdsch_enodeb PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD")
ELSE(${CUHD_FIND} EQUAL -1)
add_executable(pdsch_enodeb pdsch_enodeb.c) target_link_libraries(pdsch_ue cuhd)
target_link_libraries(pdsch_enodeb lte_rrc lte_phy cuhd) target_link_libraries(pdsch_enodeb cuhd)
ENDIF(${CUHD_FIND} EQUAL -1)
IF(${GRAPHICS_FIND} EQUAL -1) IF(${GRAPHICS_FIND} EQUAL -1)
SET_TARGET_PROPERTIES(pdsch_ue 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") SET_TARGET_PROPERTIES(pdsch_enodeb PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS")
ELSE(${GRAPHICS_FIND} EQUAL -1) ELSE(${GRAPHICS_FIND} EQUAL -1)
target_link_libraries(pdsch_ue graphics) target_link_libraries(pdsch_ue graphics)
target_link_libraries(pdsch_enodeb graphics) target_link_libraries(pdsch_enodeb graphics)
ENDIF(${GRAPHICS_FIND} EQUAL -1) ENDIF(${GRAPHICS_FIND} EQUAL -1)
ENDIF(${CUHD_FIND} GREATER -1)
################################################################# #################################################################

@ -38,9 +38,13 @@
#include "liblte/rrc/rrc.h" #include "liblte/rrc/rrc.h"
#include "liblte/phy/phy.h" #include "liblte/phy/phy.h"
#include "liblte/graphics/plot/plot_waterfall.h"
#ifndef DISABLE_UHD
#include "liblte/cuhd/cuhd.h" #include "liblte/cuhd/cuhd.h"
#include "cuhd_utils.h" #include "cuhd_utils.h"
#include "liblte/graphics/plot/plot_waterfall.h" #endif
#define STDOUT_COMPACT #define STDOUT_COMPACT
@ -70,6 +74,8 @@ typedef struct {
bool disable_plots; bool disable_plots;
int force_N_id_2; int force_N_id_2;
uint16_t rnti; uint16_t rnti;
char *input_file_name;
uint32_t file_nof_prb;
char *uhd_args; char *uhd_args;
float uhd_freq; float uhd_freq;
float uhd_gain; float uhd_gain;
@ -83,6 +89,8 @@ void args_default(prog_args_t *args) {
args->nof_subframes = -1; args->nof_subframes = -1;
args->rnti = SIRNTI; args->rnti = SIRNTI;
args->force_N_id_2 = -1; // Pick the best args->force_N_id_2 = -1; // Pick the best
args->input_file_name = NULL;
args->file_nof_prb = 6;
args->uhd_args = ""; args->uhd_args = "";
args->uhd_freq = -1.0; args->uhd_freq = -1.0;
args->uhd_gain = 60.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) { 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-a UHD args [Default %s]\n", args->uhd_args);
printf("\t-g UHD RX gain [Default %.2f dB]\n", args->uhd_gain); 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-r RNTI [Default 0x%x]\n",args->rnti);
printf("\t-l Force N_id_2 [Default best]\n"); printf("\t-l Force N_id_2 [Default best]\n");
#ifndef DISABLE_GRAPHICS #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) { void parse_args(prog_args_t *args, int argc, char **argv) {
int opt; int opt;
args_default(args); args_default(args);
while ((opt = getopt(argc, argv, "agldnvrfuUsS")) != -1) { while ((opt = getopt(argc, argv, "aglipdnvrfuUsS")) != -1) {
switch (opt) { switch (opt) {
case 'i':
args->input_file_name = argv[optind];
break;
case 'p':
args->file_nof_prb = atoi(argv[optind]);
break;
case 'a': case 'a':
args->uhd_args = argv[optind]; args->uhd_args = argv[optind];
break; break;
@ -157,7 +177,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
exit(-1); exit(-1);
} }
} }
if (args->uhd_freq < 0) { if (args->uhd_freq < 0 && args->input_file_name == NULL) {
usage(args, argv[0]); usage(args, argv[0]);
exit(-1); 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) { int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples) {
DEBUG(" ---- Receive %d samples ---- \n", nsamples); DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return cuhd_recv(h, data, nsamples, 1); return cuhd_recv(h, data, nsamples, 1);
} }
#endif
extern float mean_exec_time; extern float mean_exec_time;
@ -217,6 +239,9 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
} }
#ifndef DISABLE_UHD
if (!prog_args.input_file_name) {
printf("Opening UHD device...\n"); printf("Opening UHD device...\n");
if (cuhd_open(prog_args.uhd_args, &uhd)) { if (cuhd_open(prog_args.uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n"); fprintf(stderr, "Error opening uhd\n");
@ -252,18 +277,41 @@ int main(int argc, char **argv) {
cuhd_stop_rx_stream(uhd); cuhd_stop_rx_stream(uhd);
cuhd_flush_buffer(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)) { if (ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper, uhd)) {
fprintf(stderr, "Error initiating ue_sync\n"); fprintf(stderr, "Error initiating ue_sync\n");
exit(-1); exit(-1);
} }
}
if (ue_dl_init(&ue_dl, cell, prog_args.rnti==SIRNTI?1:prog_args.rnti)) { // This is the User RNTI 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"); fprintf(stderr, "Error initiating UE downlink processing module\n");
exit(-1); 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 */ /* 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); ue_dl_set_rnti(&ue_dl, prog_args.rnti);
@ -274,13 +322,17 @@ int main(int argc, char **argv) {
// Register Ctrl+C handler // Register Ctrl+C handler
signal(SIGINT, sig_int_handler); signal(SIGINT, sig_int_handler);
#ifndef DISABLE_GRAPHICS #ifndef DISABLE_GRAPHICS
if (!prog_args.disable_plots) { if (!prog_args.disable_plots) {
init_plots(cell); init_plots(cell);
} }
#endif #endif
#ifndef DISABLE_UHD
if (!prog_args.input_file_name) {
cuhd_start_rx_stream(uhd); cuhd_start_rx_stream(uhd);
}
#endif
// Variables for measurements // Variables for measurements
uint32_t nframes=0; uint32_t nframes=0;
@ -389,7 +441,7 @@ int main(int argc, char **argv) {
} }
#ifndef DISABLE_GRAPHICS #ifndef DISABLE_GRAPHICS
if (!prog_args.disable_plots) { 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 #endif
} else if (ret == 0) { } else if (ret == 0) {
@ -402,9 +454,14 @@ int main(int argc, char **argv) {
} // Main loop } // Main loop
ue_dl_free(&ue_dl); ue_dl_free(&ue_dl);
ue_mib_free(&ue_mib);
ue_sync_free(&ue_sync); ue_sync_free(&ue_sync);
#ifndef DISABLE_UHD
if (!prog_args.input_file_name) {
ue_mib_free(&ue_mib);
cuhd_close(uhd); cuhd_close(uhd);
}
#endif
printf("\nBye\n"); printf("\nBye\n");
exit(0); 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_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)); 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); 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, vec_sc_prod_fff(qs->strack.pss.conv_output_avg,
1/qs->strack.pss.conv_output_avg[max], 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); qs->strack.pss.frame_size+qs->strack.pss.fft_size-1);
plot_real_setNewData(&p_sync, tmp_plot2, qs->strack.pss.frame_size); 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, q->pdsch.pdsch_d, nof_symbols);
plot_scatter_setNewData(&pscatequal_pdcch, q->pdcch.pdcch_d, 36*q->pdcch.nof_cce); 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/ch_estimation/chest_dl.h"
#include "liblte/phy/phch/pbch.h" #include "liblte/phy/phch/pbch.h"
#include "liblte/phy/common/fft.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 * should be called regularly, returning every 1 ms. It reads from the
* USRP, aligns the samples to the subframe and performs time/freq synch. * 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 * The function returns 1 when the signal is correctly acquired and the
* returned buffer is aligned with the subframe. * returned buffer is aligned with the subframe.
* *
@ -62,6 +66,9 @@ typedef struct LIBLTE_API {
void *stream; void *stream;
int (*recv_callback)(void*, void*, uint32_t); int (*recv_callback)(void*, void*, uint32_t);
filesource_t file_source;
bool file_mode;
ue_sync_state_t state; ue_sync_state_t state;
cf_t *input_buffer; 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), int (recv_callback)(void*, void*, uint32_t),
void *stream_handler); 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 void ue_sync_free(ue_sync_t *q);
LIBLTE_API uint32_t ue_sync_sf_len(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); int r = pdsch_decode(&pdsch, input_fft, ce, noise_power, data, sf_idx, &harq_process, rv);
tbs_is_zero:
if (nlhs >= 1) { if (nlhs >= 1) {
plhs[0] = mxCreateLogicalScalar(r == 0); plhs[0] = mxCreateLogicalScalar(r == 0);
} }

@ -34,9 +34,11 @@
#include "liblte/phy/ue/ue_sync.h" #include "liblte/phy/ue/ue_sync.h"
#include "liblte/phy/io/filesource.h"
#include "liblte/phy/utils/debug.h" #include "liblte/phy/utils/debug.h"
#include "liblte/phy/utils/vector.h" #include "liblte/phy/utils/vector.h"
#define MAX_TIME_OFFSET 128 #define MAX_TIME_OFFSET 128
cf_t dummy[MAX_TIME_OFFSET]; cf_t dummy[MAX_TIME_OFFSET];
@ -44,6 +46,40 @@ cf_t dummy[MAX_TIME_OFFSET];
#define TRACK_FRAME_SIZE 32 #define TRACK_FRAME_SIZE 32
#define FIND_NOF_AVG_FRAMES 2 #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, int ue_sync_init(ue_sync_t *q,
lte_cell_t cell, lte_cell_t cell,
int (recv_callback)(void*, void*, uint32_t), int (recv_callback)(void*, void*, uint32_t),
@ -65,6 +101,7 @@ int ue_sync_init(ue_sync_t *q,
q->cell = cell; q->cell = cell;
q->fft_size = lte_symbol_sz(q->cell.nof_prb); q->fft_size = lte_symbol_sz(q->cell.nof_prb);
q->sf_len = SF_LEN(q->fft_size); q->sf_len = SF_LEN(q->fft_size);
q->file_mode = false;
if (cell.id == 1000) { if (cell.id == 1000) {
/* If the cell is unkown, decode SSS on track state */ /* 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) { if (q->input_buffer) {
free(q->input_buffer); free(q->input_buffer);
} }
if (!q->file_mode) {
sync_free(&q->sfind); sync_free(&q->sfind);
sync_free(&q->strack); sync_free(&q->strack);
} else {
filesource_free(&q->file_source);
}
bzero(q, sizeof(ue_sync_t)); bzero(q, sizeof(ue_sync_t));
} }
@ -185,9 +225,11 @@ 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) { void ue_sync_set_N_id_2(ue_sync_t *q, uint32_t N_id_2) {
if (!q->file_mode) {
ue_sync_reset(q); ue_sync_reset(q);
sync_set_N_id_2(&q->strack, N_id_2); sync_set_N_id_2(&q->strack, N_id_2);
sync_set_N_id_2(&q->sfind, N_id_2); sync_set_N_id_2(&q->sfind, N_id_2);
}
} }
static int find_peak_ok(ue_sync_t *q) { static int find_peak_ok(ue_sync_t *q) {
@ -229,7 +271,7 @@ static int find_peak_ok(ue_sync_t *q) {
return 0; 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 */ /* Make sure subframe idx is what we expect */
if ((q->sf_idx != sync_get_sf_idx(&q->strack)) && q->decode_sss_on_track) { 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; 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 */ /* if we missed too many PSS go back to FIND */
q->frame_no_cnt++; 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) 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)) { if (receive_samples(q)) {
fprintf(stderr, "Error receiving samples\n"); fprintf(stderr, "Error receiving samples\n");
return -1; return LIBLTE_ERROR;
} }
switch (q->state) { switch (q->state) {
@ -390,13 +456,20 @@ int ue_sync_get_buffer(ue_sync_t *q, cf_t **sf_symbols) {
break; break;
} }
}
} }
return ret; return ret;
} }
void ue_sync_reset(ue_sync_t *q) { void ue_sync_reset(ue_sync_t *q) {
q->state = SF_FIND;
if (!q->file_mode) {
sync_reset(&q->strack); sync_reset(&q->strack);
} else {
q->sf_idx = 9;
}
q->state = SF_FIND;
q->frame_ok_cnt = 0; q->frame_ok_cnt = 0;
q->frame_no_cnt = 0; q->frame_no_cnt = 0;
q->frame_total_cnt = 0; q->frame_total_cnt = 0;

Loading…
Cancel
Save