mirror of https://github.com/PentHertz/srsLTE.git
Fixed BUG in ue_mib.c not checking if enough buffer. Fixed ud_dl rv_idx. Removed iodev.c
This commit is contained in:
parent
8531fb1a0c
commit
5193112041
|
@ -51,7 +51,7 @@ LIST(FIND OPTIONAL_LIBS graphics GRAPHICS_FIND)
|
|||
# These two can be compiled without UHD or graphics support
|
||||
#################################################################
|
||||
|
||||
add_executable(pdsch_ue pdsch_ue.c iodev.c cell_search_utils.c)
|
||||
add_executable(pdsch_ue pdsch_ue.c cell_search_utils.c)
|
||||
target_link_libraries(pdsch_ue lte_rrc lte_phy)
|
||||
|
||||
add_executable(pdsch_enodeb pdsch_enodeb.c)
|
||||
|
|
|
@ -141,7 +141,7 @@ int main(int argc, char **argv) {
|
|||
int n;
|
||||
uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_unpacked[BCH_PAYLOAD_LEN];
|
||||
uint32_t sfn_offset;
|
||||
float rssi=0, rsrp=0, rsrq=0;
|
||||
float rssi=0, rsrp=0, rsrq=0, snr=0;
|
||||
cf_t *nullce[MAX_PORTS];
|
||||
|
||||
for (int i=0;i<MAX_PORTS;i++) {
|
||||
|
@ -231,7 +231,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
break;
|
||||
case DECODE_SIB:
|
||||
sfn=0;
|
||||
sfn=0; // FIXME: Use correct SFN!!
|
||||
/* We are looking for SI Blocks, search only in appropiate places */
|
||||
if ((ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) {
|
||||
n = ue_dl_decode(&ue_dl, sf_buffer, data, ue_sync_get_sfidx(&ue_sync), sfn, SIRNTI);
|
||||
|
@ -267,15 +267,18 @@ int main(int argc, char **argv) {
|
|||
rssi = VEC_CMA(chest_dl_get_rssi(&chest),rssi,nframes);
|
||||
rsrq = VEC_CMA(chest_dl_get_rsrq(&chest),rsrq,nframes);
|
||||
rsrp = VEC_CMA(chest_dl_get_rsrp(&chest),rsrp,nframes);
|
||||
float noise = chest_dl_get_noise_estimate(&chest);
|
||||
snr = VEC_CMA(rssi/(noise*noise*2*cell.nof_ports*fft.symbol_sz),snr,nframes);
|
||||
nframes++;
|
||||
|
||||
// Plot and Printf
|
||||
if ((nframes%10) == 0) {
|
||||
printf("CFO: %+6.4f KHz, SFO: %+6.4f Khz, RSSI: %+5.2f dBm, RSRP: %+4.2f dBm, RSRQ: %4.2f dB\r",
|
||||
printf("CFO: %+8.4f KHz, SFO: %+8.4f Khz, RSSI: %+5.1f dBm, "
|
||||
"RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %5.1f dB\r",
|
||||
ue_sync_get_cfo(&ue_sync)/1000, ue_sync_get_sfo(&ue_sync)/1000,
|
||||
10*log10(rssi*1000/4/cell.nof_prb/12/2)-prog_args.uhd_gain,
|
||||
10*log10(rsrp*1000)-prog_args.uhd_gain,
|
||||
10*log10(rsrq));
|
||||
10*log10(rsrq), 10*log10(snr));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,207 +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 <unistd.h>
|
||||
|
||||
#include "iodev.h"
|
||||
|
||||
#include "liblte/phy/io/filesource.h"
|
||||
#include "liblte/phy/ue/ue_sync.h"
|
||||
#include "liblte/phy/utils/debug.h"
|
||||
#include "liblte/phy/utils/vector.h"
|
||||
|
||||
#ifndef DISABLE_UHD
|
||||
#include "liblte/cuhd/cuhd.h"
|
||||
#endif
|
||||
|
||||
#include "cell_search_utils.h"
|
||||
|
||||
|
||||
int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples) {
|
||||
DEBUG(" ---- Receive %d samples ---- \n", nsamples);
|
||||
return cuhd_recv(h, data, nsamples, 1);
|
||||
}
|
||||
|
||||
/* Setup USRP or input file */
|
||||
int iodev_init(iodev_t *q, iodev_cfg_t *config, lte_cell_t *cell) {
|
||||
|
||||
if (config->input_file_name) {
|
||||
|
||||
cell->phich_resources = R_1;
|
||||
cell->phich_length = PHICH_NORM;
|
||||
|
||||
cell->id = config->cell_id_file;
|
||||
cell->cp = CPNORM;
|
||||
cell->nof_ports = config->nof_ports_file;
|
||||
cell->nof_prb = config->nof_prb_file;
|
||||
|
||||
if (filesource_init(&q->fsrc, config->input_file_name, COMPLEX_FLOAT_BIN)) {
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
q->mode = FILESOURCE;
|
||||
int symbol_sz = lte_symbol_sz(cell->nof_prb);
|
||||
if (symbol_sz > 0) {
|
||||
q->sf_len = SF_LEN(symbol_sz);
|
||||
} else {
|
||||
fprintf(stderr, "Invalid number of PRB %d\n", cell->nof_prb);
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
|
||||
q->input_buffer_file = vec_malloc(q->sf_len * sizeof(cf_t));
|
||||
if (!q->input_buffer_file) {
|
||||
perror("malloc");
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
q->sf_idx = 9;
|
||||
|
||||
} else {
|
||||
|
||||
#ifndef DISABLE_UHD
|
||||
|
||||
printf("Opening UHD device...\n");
|
||||
if (cuhd_open(config->uhd_args, &q->uhd)) {
|
||||
fprintf(stderr, "Error opening uhd\n");
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
/* Set receiver gain */
|
||||
cuhd_set_rx_gain(q->uhd, config->uhd_gain);
|
||||
|
||||
/* set receiver frequency */
|
||||
cuhd_set_rx_freq(q->uhd, (double) config->uhd_freq);
|
||||
cuhd_rx_wait_lo_locked(q->uhd);
|
||||
DEBUG("Set uhd_freq to %.3f MHz\n", (double ) config->uhd_freq);
|
||||
|
||||
cell_detect_cfg_t detect_config;
|
||||
bzero(&detect_config, sizeof(cell_detect_cfg_t));
|
||||
|
||||
if (detect_and_decode_cell(&detect_config, q->uhd, config->force_N_id_2, cell)) {
|
||||
fprintf(stderr, "Cell not found\n");
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
|
||||
cuhd_start_rx_stream(q->uhd);
|
||||
|
||||
if (ue_sync_init(&q->sframe, *cell, cuhd_recv_wrapper, q->uhd)) {
|
||||
fprintf(stderr, "Error initiating ue_sync\n");
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
|
||||
// Here, the subframe length and input buffer is managed by ue_sync
|
||||
q->mode = UHD;
|
||||
|
||||
#else
|
||||
printf("Error UHD not available. Select an input file\n");
|
||||
return LIBLTE_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
memcpy(&q->config, config, sizeof(iodev_cfg_t));
|
||||
|
||||
return LIBLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void iodev_free(iodev_t *q) {
|
||||
|
||||
if (q->mode == FILESOURCE) {
|
||||
filesource_free(&q->fsrc);
|
||||
} else {
|
||||
#ifndef DISABLE_UHD
|
||||
cuhd_close(q->uhd);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* Receive samples from the USRP or read from file */
|
||||
int iodev_receive(iodev_t *q, cf_t **buffer) {
|
||||
int n;
|
||||
if (q->mode == FILESOURCE) {
|
||||
INFO(" ----- READING %d SAMPLES ---- \n", q->sf_len);
|
||||
n = filesource_read(&q->fsrc, q->input_buffer_file, q->sf_len);
|
||||
*buffer = q->input_buffer_file;
|
||||
if (n == -1) {
|
||||
fprintf(stderr, "Error reading file\n");
|
||||
/* wrap file if arrive to end */
|
||||
} else if (n < q->sf_len) {
|
||||
DEBUG("Read %d from file. Seeking to 0\n",n);
|
||||
filesource_seek(&q->fsrc, 0);
|
||||
n = filesource_read(&q->fsrc, q->input_buffer_file, q->sf_len);
|
||||
if (n == -1) {
|
||||
fprintf(stderr, "Error reading file\n");
|
||||
/* wrap file if arrive to end */
|
||||
} else {
|
||||
n = 1;
|
||||
}
|
||||
} else {
|
||||
n = 1;
|
||||
}
|
||||
q->sf_idx++;
|
||||
if (q->sf_idx == 10) {
|
||||
q->sf_idx = 0;
|
||||
}
|
||||
usleep(5000);
|
||||
} else {
|
||||
/* Use ue_sync_work which returns a synchronized buffer of subframe samples */
|
||||
#ifndef DISABLE_UHD
|
||||
n = ue_sync_get_buffer(&q->sframe, buffer);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error calling ue_sync_work()\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void* iodev_get_cuhd(iodev_t *q) {
|
||||
if (q->mode == UHD) {
|
||||
return q->uhd;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool iodev_isfile(iodev_t *q) {
|
||||
return q->mode == FILESOURCE;
|
||||
}
|
||||
|
||||
bool iodev_isUSRP(iodev_t *q) {
|
||||
return q->mode == UHD;
|
||||
}
|
||||
|
||||
uint32_t iodev_get_sfidx(iodev_t *q) {
|
||||
if (iodev_isfile(q)) {
|
||||
return q->sf_idx;
|
||||
} else {
|
||||
return ue_sync_get_sfidx(&q->sframe);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,99 +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/.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef IODEF_H
|
||||
#define IODEF_H
|
||||
|
||||
#include "liblte/config.h"
|
||||
|
||||
#include "liblte/phy/ue/ue_sync.h"
|
||||
#include "liblte/phy/io/filesource.h"
|
||||
|
||||
#ifndef DISABLE_UHD
|
||||
#include "liblte/cuhd/cuhd.h"
|
||||
#endif
|
||||
|
||||
/*********
|
||||
*
|
||||
* This component is a wrapper to the cuhd or filesource modules. It uses
|
||||
* sync_frame_t to read aligned subframes from the USRP or filesource to read
|
||||
* subframes from a file.
|
||||
*
|
||||
* When created, it starts receiving/reading at 1.92 MHz. The sampling frequency
|
||||
* can then be changed using iodev_set_srate()
|
||||
*/
|
||||
|
||||
|
||||
typedef enum LIBLTE_API {FILESOURCE, UHD} iodev_mode_t;
|
||||
|
||||
typedef _Complex float cf_t;
|
||||
|
||||
typedef struct LIBLTE_API {
|
||||
char *input_file_name;
|
||||
uint32_t cell_id_file;
|
||||
uint32_t nof_prb_file;
|
||||
uint32_t nof_ports_file;
|
||||
int force_N_id_2;
|
||||
|
||||
float uhd_freq;
|
||||
float uhd_gain;
|
||||
char *uhd_args;
|
||||
float find_threshold;
|
||||
} iodev_cfg_t;
|
||||
|
||||
typedef struct LIBLTE_API {
|
||||
#ifndef DISABLE_UHD
|
||||
void *uhd;
|
||||
ue_sync_t sframe;
|
||||
#endif
|
||||
uint32_t sf_len;
|
||||
uint32_t sf_idx;
|
||||
cf_t *input_buffer_file; // for UHD mode, the input buffer is managed by sync_frame_t
|
||||
filesource_t fsrc;
|
||||
iodev_cfg_t config;
|
||||
iodev_mode_t mode;
|
||||
} iodev_t;
|
||||
|
||||
|
||||
LIBLTE_API int iodev_init(iodev_t *q,
|
||||
iodev_cfg_t *config,
|
||||
lte_cell_t *cell);
|
||||
|
||||
LIBLTE_API void iodev_free(iodev_t *q);
|
||||
|
||||
LIBLTE_API int iodev_receive(iodev_t *q,
|
||||
cf_t **buffer);
|
||||
|
||||
LIBLTE_API void* iodev_get_cuhd(iodev_t *q);
|
||||
|
||||
LIBLTE_API uint32_t iodev_get_sfidx(iodev_t *q);
|
||||
|
||||
LIBLTE_API bool iodev_isfile(iodev_t *q);
|
||||
|
||||
LIBLTE_API bool iodev_isUSRP(iodev_t *q);
|
||||
|
||||
#endif
|
|
@ -36,105 +36,76 @@
|
|||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "liblte/rrc/rrc.h"
|
||||
#include "liblte/phy/phy.h"
|
||||
#include "iodev.h"
|
||||
#include "liblte/cuhd/cuhd.h"
|
||||
#include "cell_search_utils.h"
|
||||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
void init_plots();
|
||||
void do_plots(ue_dl_t *q, uint32_t sf_idx);
|
||||
#endif
|
||||
|
||||
int go_exit = 0;
|
||||
|
||||
/* Local function definitions */
|
||||
void init_plots();
|
||||
cell_detect_cfg_t cell_detect_config = {
|
||||
500, // nof_frames_total
|
||||
50, // nof_frames_detected
|
||||
CS_FIND_THRESHOLD // threshold
|
||||
};
|
||||
|
||||
/**********************************************************************
|
||||
* Program arguments processing
|
||||
***********************************************************************/
|
||||
typedef struct {
|
||||
uint16_t rnti;
|
||||
int nof_subframes;
|
||||
bool disable_plots;
|
||||
iodev_cfg_t io_config;
|
||||
int force_N_id_2;
|
||||
char *uhd_args;
|
||||
float uhd_freq;
|
||||
float uhd_gain;
|
||||
}prog_args_t;
|
||||
|
||||
void args_default(prog_args_t *args) {
|
||||
args->io_config.cell_id_file = 195;
|
||||
args->io_config.nof_prb_file = 50;
|
||||
args->io_config.nof_ports_file = 2;
|
||||
args->rnti = SIRNTI;
|
||||
args->nof_subframes = -1;
|
||||
args->disable_plots = false;
|
||||
args->io_config.find_threshold = -1.0;
|
||||
args->io_config.input_file_name = NULL;
|
||||
args->io_config.force_N_id_2 = -1; // Pick the best
|
||||
args->io_config.uhd_args = "";
|
||||
args->io_config.uhd_freq = -1.0;
|
||||
args->io_config.uhd_gain = 60.0;
|
||||
args->force_N_id_2 = -1; // Pick the best
|
||||
args->uhd_args = "";
|
||||
args->uhd_freq = -1.0;
|
||||
args->uhd_gain = 60.0;
|
||||
}
|
||||
|
||||
void usage(prog_args_t *args, char *prog) {
|
||||
printf("Usage: %s [cargndvtbl] [-i input_file | -f rx_frequency (in Hz)]\n", prog);
|
||||
printf("\t-c cell_id if reading from file [Default %d]\n", args->io_config.cell_id_file);
|
||||
printf("\t-p nof_prb if reading from file [Default %d]\n", args->io_config.nof_prb_file);
|
||||
printf("\t-o nof_ports if reading from file [Default %d]\n", args->io_config.nof_ports_file);
|
||||
printf("\t-r RNTI to look for [Default 0x%x]\n", args->rnti);
|
||||
#ifndef DISABLE_UHD
|
||||
printf("\t-a UHD args [Default %s]\n", args->io_config.uhd_args);
|
||||
printf("\t-g UHD RX gain [Default %.2f dB]\n", args->io_config.uhd_gain);
|
||||
#else
|
||||
printf("\t UHD is disabled. CUHD library not available\n");
|
||||
#endif
|
||||
printf("Usage: %s [agldnv] -f rx_frequency (in Hz)\n", prog);
|
||||
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-l Force N_id_2 [Default best]\n");
|
||||
printf("\t-b Decode PBCH only [Default All channels]\n");
|
||||
printf("\t-n nof_subframes [Default %d]\n", args->nof_subframes);
|
||||
printf("\t-t PSS threshold [Default %f]\n", args->io_config.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-n nof_subframes [Default %d]\n", args->nof_subframes);
|
||||
printf("\t-v [set verbose to debug, default none]\n");
|
||||
}
|
||||
|
||||
void parse_args(prog_args_t *args, int argc, char **argv) {
|
||||
int opt;
|
||||
args_default(args);
|
||||
while ((opt = getopt(argc, argv, "icagfndvtbprol")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "agldnvf")) != -1) {
|
||||
switch (opt) {
|
||||
case 'i':
|
||||
args->io_config.input_file_name = argv[optind];
|
||||
break;
|
||||
case 'c':
|
||||
args->io_config.cell_id_file = atoi(argv[optind]);
|
||||
break;
|
||||
case 'p':
|
||||
args->io_config.nof_prb_file = atoi(argv[optind]);
|
||||
break;
|
||||
case 'o':
|
||||
args->io_config.nof_ports_file = atoi(argv[optind]);
|
||||
break;
|
||||
case 'a':
|
||||
args->io_config.uhd_args = argv[optind];
|
||||
args->uhd_args = argv[optind];
|
||||
break;
|
||||
case 'g':
|
||||
args->io_config.uhd_gain = atof(argv[optind]);
|
||||
args->uhd_gain = atof(argv[optind]);
|
||||
break;
|
||||
case 'f':
|
||||
args->io_config.uhd_freq = atof(argv[optind]);
|
||||
break;
|
||||
case 't':
|
||||
args->io_config.find_threshold = atof(argv[optind]);
|
||||
args->uhd_freq = atof(argv[optind]);
|
||||
break;
|
||||
case 'n':
|
||||
args->nof_subframes = atoi(argv[optind]);
|
||||
break;
|
||||
case 'l':
|
||||
args->io_config.force_N_id_2 = atoi(argv[optind]);
|
||||
break;
|
||||
case 'r':
|
||||
args->rnti= atoi(argv[optind]);
|
||||
args->force_N_id_2 = atoi(argv[optind]);
|
||||
break;
|
||||
case 'd':
|
||||
args->disable_plots = true;
|
||||
|
@ -147,105 +118,160 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
|
|||
exit(-1);
|
||||
}
|
||||
}
|
||||
if (args->io_config.uhd_freq < 0 && args->io_config.input_file_name == NULL) {
|
||||
if (args->uhd_freq < 0) {
|
||||
usage(args, argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
/**********************************************************************/
|
||||
|
||||
void sigintHandler(int x) {
|
||||
go_exit = 1;
|
||||
}
|
||||
|
||||
/* TODO: Do something with the output data */
|
||||
uint8_t data[10000];
|
||||
uint8_t data[10000], data_unpacked[1000];
|
||||
|
||||
int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples) {
|
||||
DEBUG(" ---- Receive %d samples ---- \n", nsamples);
|
||||
return cuhd_recv(h, data, nsamples, 1);
|
||||
}
|
||||
|
||||
extern float mean_exec_time;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int ret;
|
||||
cf_t *sf_buffer;
|
||||
iodev_t iodev;
|
||||
prog_args_t prog_args;
|
||||
lte_cell_t cell;
|
||||
ue_dl_t ue_dl;
|
||||
int64_t sf_cnt;
|
||||
bool printed_sib = false;
|
||||
int rlen;
|
||||
ue_sync_t ue_sync;
|
||||
ue_mib_t ue_mib;
|
||||
void *uhd;
|
||||
ue_dl_t ue_dl;
|
||||
lte_fft_t fft;
|
||||
chest_dl_t chest;
|
||||
uint32_t nof_trials = 0;
|
||||
uint32_t sfn = 0; // system frame number
|
||||
int n;
|
||||
uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_unpacked[BCH_PAYLOAD_LEN];
|
||||
uint32_t sfn_offset;
|
||||
|
||||
parse_args(&prog_args, argc, argv);
|
||||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
if (!prog_args.disable_plots) {
|
||||
init_plots();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Initialize subframe counter */
|
||||
sf_cnt = 0;
|
||||
printf("Opening UHD device...\n");
|
||||
if (cuhd_open(prog_args.uhd_args, &uhd)) {
|
||||
fprintf(stderr, "Error opening uhd\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Set receiver gain */
|
||||
cuhd_set_rx_gain(uhd, prog_args.uhd_gain);
|
||||
|
||||
if (iodev_init(&iodev, &prog_args.io_config, &cell)) {
|
||||
/* set receiver frequency */
|
||||
cuhd_set_rx_freq(uhd, (double) prog_args.uhd_freq);
|
||||
cuhd_rx_wait_lo_locked(uhd);
|
||||
printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000);
|
||||
|
||||
if (detect_and_decode_cell(&cell_detect_config, uhd, prog_args.force_N_id_2, &cell)) {
|
||||
fprintf(stderr, "Cell not found\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
cuhd_start_rx_stream(uhd);
|
||||
|
||||
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, 1234)) {
|
||||
fprintf(stderr, "Error initiating UE downlink processing module\n");
|
||||
exit(-1);
|
||||
}
|
||||
pdsch_set_rnti(&ue_dl.pdsch, prog_args.rnti);
|
||||
if (ue_mib_init_known_cell(&ue_mib, cell, false)) {
|
||||
fprintf(stderr, "Error initaiting UE MIB decoder\n");
|
||||
exit(-1);
|
||||
}
|
||||
pdsch_set_rnti(&ue_dl.pdsch, SIRNTI);
|
||||
|
||||
/* Initialize subframe counter */
|
||||
sf_cnt = 0;
|
||||
|
||||
if (lte_fft_init(&fft, cell.cp, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initiating FFT\n");
|
||||
return -1;
|
||||
}
|
||||
if (chest_dl_init(&chest, cell)) {
|
||||
fprintf(stderr, "Error initiating channel estimator\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Main loop */
|
||||
while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
|
||||
while (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) {
|
||||
|
||||
ret = iodev_receive(&iodev, &sf_buffer);
|
||||
ret = ue_sync_get_buffer(&ue_sync, &sf_buffer);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error reading from input device (%d)\n", ret);
|
||||
break;
|
||||
fprintf(stderr, "Error calling ue_sync_work()\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "Change in ue_dl API\n");
|
||||
exit(-1);
|
||||
|
||||
/* iodev_receive returns 1 if successfully read 1 aligned subframe */
|
||||
/* ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */
|
||||
if (ret == 1) {
|
||||
rlen = ue_dl_decode(&ue_dl, sf_buffer, data, iodev_get_sfidx(&iodev), 0, prog_args.rnti);
|
||||
if (rlen < 0) {
|
||||
fprintf(stderr, "\nError running receiver\n");fflush(stdout);
|
||||
if (ue_sync_get_sfidx(&ue_sync) == 0) {
|
||||
pbch_decode_reset(&ue_mib.pbch);
|
||||
n = ue_mib_decode_aligned_frame(&ue_mib,
|
||||
sf_buffer, bch_payload_unpacked,
|
||||
NULL, &sfn_offset);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error decoding UE MIB\n");
|
||||
exit(-1);
|
||||
} else if (n == MIB_FOUND) {
|
||||
bit_unpack_vector(bch_payload_unpacked, bch_payload, BCH_PAYLOAD_LEN);
|
||||
bcch_bch_unpack(bch_payload, BCH_PAYLOAD_LEN, &cell, &sfn);
|
||||
sfn = (sfn + sfn_offset)%1024;
|
||||
}
|
||||
if (prog_args.rnti == SIRNTI && !printed_sib && rlen > 0) {
|
||||
printf("\n\nDecoded SIB1 Message: ");
|
||||
vec_fprint_hex(stdout, data, rlen);
|
||||
printf("\n");fflush(stdout);
|
||||
printed_sib = true;
|
||||
}
|
||||
/* We are looking for SI Blocks, search only in appropiate places */
|
||||
if ((ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) {
|
||||
n = ue_dl_decode(&ue_dl, sf_buffer, data, ue_sync_get_sfidx(&ue_sync), sfn, SIRNTI);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
|
||||
exit(-1);
|
||||
} else if (n == 0) {
|
||||
printf("CFO: %+8.4f KHz, SFO: %+8.4f Khz, ExecTime: %6.1f us, NOI: %.2f,"
|
||||
"PDCCH-Det: %.3f, PDSCH-BLER: %.3f\r",
|
||||
ue_sync_get_cfo(&ue_sync)/1000, ue_sync_get_sfo(&ue_sync)/1000,
|
||||
mean_exec_time, pdsch_average_noi(&ue_dl.pdsch),
|
||||
(float) ue_dl.nof_pdcch_detected/nof_trials,
|
||||
(float) ue_dl.pkt_errors/ue_dl.pkts_total,nof_trials);
|
||||
|
||||
// Plot and Printf
|
||||
if (!(sf_cnt % 10)) {
|
||||
printf("CFO: %+.4f KHz, SFO: %+.4f Khz, NOI: %.2f Errors: %4d/%4d, BLER: %.1e, Texec: %.2f\r",
|
||||
ue_sync_get_cfo(&iodev.sframe)/1000, ue_sync_get_sfo(&iodev.sframe)/1000,
|
||||
pdsch_average_noi(&ue_dl.pdsch),
|
||||
(int) ue_dl.pkt_errors, (int) ue_dl.pkts_total, (float) ue_dl.pkt_errors / ue_dl.pkts_total,
|
||||
mean_exec_time);
|
||||
|
||||
}
|
||||
nof_trials++;
|
||||
}
|
||||
} else if (ret == 0) {
|
||||
/*printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r",
|
||||
sync_get_peak_value(&ue_sync.sfind),
|
||||
ue_sync.frame_total_cnt, ue_sync.state);
|
||||
*/
|
||||
}
|
||||
if (ue_sync_get_sfidx(&ue_sync) == 9) {
|
||||
sfn++;
|
||||
if (sfn == 1024) {
|
||||
sfn = 0;
|
||||
}
|
||||
}
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
if (!prog_args.disable_plots && iodev_get_sfidx(&iodev) == 5) {
|
||||
if (!prog_args.disable_plots && ue_sync_get_sfidx(&ue_sync) == 5) {
|
||||
do_plots(&ue_dl, 5);
|
||||
}
|
||||
#endif
|
||||
} else if (ret == 0) {
|
||||
printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r",
|
||||
sync_get_peak_value(&iodev.sframe.sfind),
|
||||
iodev.sframe.frame_total_cnt, iodev.sframe.state);
|
||||
}
|
||||
|
||||
|
||||
sf_cnt++;
|
||||
} // Main loop
|
||||
|
||||
ue_dl_free(&ue_dl);
|
||||
iodev_free(&iodev);
|
||||
|
||||
ue_sync_free(&ue_sync);
|
||||
cuhd_close(uhd);
|
||||
printf("\nBye\n");
|
||||
exit(0);
|
||||
}
|
||||
|
@ -253,6 +279,10 @@ int main(int argc, char **argv) {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Plotting Functions
|
||||
***********************************************************************/
|
||||
|
|
|
@ -410,7 +410,6 @@ int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS], float
|
|||
}
|
||||
if (bch_payload) {
|
||||
memcpy(bch_payload, q->data, sizeof(uint8_t) * BCH_PAYLOAD_LEN);
|
||||
vec_fprint_hex(stdout, bch_payload, BCH_PAYLOAD_LEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -547,8 +547,6 @@ int pdsch_decode_tb(pdsch_t *q, uint8_t *data, uint32_t tbs, uint32_t nb_e,
|
|||
return LIBLTE_ERROR;
|
||||
}
|
||||
|
||||
vec_save_file("tdec_in.dat",q->cb_out, sizeof(float) * (3 * cb_len + 12));
|
||||
|
||||
/* Turbo Decoding with CRC-based early stopping */
|
||||
q->nof_iterations = 0;
|
||||
bool early_stop = false;
|
||||
|
@ -688,8 +686,6 @@ int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_
|
|||
nof_symbols / q->cell.nof_ports);
|
||||
}
|
||||
|
||||
vec_save_file("pdsch_after.dat",q->pdsch_d,sizeof(cf_t)*nof_symbols);
|
||||
|
||||
/* demodulate symbols
|
||||
* The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
|
||||
* thus we don't need tot set it in the LLRs normalization
|
||||
|
@ -701,8 +697,6 @@ int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_
|
|||
/* descramble */
|
||||
scrambling_f_offset(&q->seq_pdsch[subframe], q->pdsch_e, 0, nof_bits_e);
|
||||
|
||||
vec_save_file("pdsch_llr.dat",q->pdsch_e,sizeof(float)*nof_bits_e);
|
||||
|
||||
return pdsch_decode_tb(q, data, nof_bits, nof_bits_e, harq_process, rv_idx);
|
||||
} else {
|
||||
return LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
|
|
@ -228,7 +228,7 @@ int main(int argc, char **argv) {
|
|||
int ret;
|
||||
uint8_t *data;
|
||||
dci_location_t locations[MAX_CANDIDATES];
|
||||
uint32_t nof_locations;
|
||||
uint32_t nof_locations = 0;
|
||||
dci_msg_t dci_msg;
|
||||
|
||||
data = malloc(100000);
|
||||
|
|
|
@ -148,8 +148,6 @@ int main(int argc, char **argv) {
|
|||
memset(fft_buffer, 0, sizeof(cf_t) * FLEN);
|
||||
lte_ifft_run_slot(&ifft, buffer, &fft_buffer[offset]);
|
||||
|
||||
vec_save_file("input", fft_buffer, sizeof(cf_t) * FLEN);
|
||||
|
||||
if (sync_find(&sync, fft_buffer, 0, &find_idx) < 0) {
|
||||
fprintf(stderr, "Error running sync_find\n");
|
||||
exit(-1);
|
||||
|
|
|
@ -174,15 +174,11 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32
|
|||
/* Get channel estimates for each port */
|
||||
chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, sf_idx);
|
||||
|
||||
gettimeofday(&t[2], NULL);
|
||||
get_time_interval(t);
|
||||
mean_exec_time = (float) VEC_CMA((float) t[0].tv_usec, mean_exec_time, frame_cnt);
|
||||
|
||||
frame_cnt++;
|
||||
|
||||
|
||||
/* First decode PCFICH and obtain CFI */
|
||||
if (pcfich_decode(&q->pcfich, q->sf_symbols, q->ce, chest_dl_get_noise_estimate(&q->chest), sf_idx, &cfi, &cfi_distance)<0) {
|
||||
if (pcfich_decode(&q->pcfich, q->sf_symbols, q->ce,
|
||||
chest_dl_get_noise_estimate(&q->chest), sf_idx, &cfi, &cfi_distance)<0) {
|
||||
fprintf(stderr, "Error decoding PCFICH\n");
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
|
@ -231,20 +227,8 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32
|
|||
|
||||
uint32_t rvidx;
|
||||
if (rnti == SIRNTI) {
|
||||
switch((sfn%8)/2) {
|
||||
case 0:
|
||||
rvidx = 0;
|
||||
break;
|
||||
case 1:
|
||||
rvidx = 2;
|
||||
break;
|
||||
case 2:
|
||||
rvidx = 3;
|
||||
break;
|
||||
case 3:
|
||||
rvidx = 1;
|
||||
break;
|
||||
}
|
||||
int k = ((sfn)/2)%4;
|
||||
rvidx = ((int) ceilf((float)3*k/2))%4;
|
||||
} else {
|
||||
rvidx = ra_dl.rv_idx;
|
||||
}
|
||||
|
@ -259,11 +243,7 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32
|
|||
ret = pdsch_decode(&q->pdsch, q->sf_symbols, q->ce, chest_dl_get_noise_estimate(&q->chest), data, sf_idx,
|
||||
&q->harq_process[0], rvidx);
|
||||
if (ret == LIBLTE_ERROR) {
|
||||
if (rnti == SIRNTI && rvidx == 1) {
|
||||
q->pkt_errors++;
|
||||
} else if (rnti != SIRNTI) {
|
||||
q->pkt_errors++;
|
||||
}
|
||||
} else if (ret == LIBLTE_ERROR_INVALID_INPUTS) {
|
||||
fprintf(stderr, "Error calling pdsch_decode()\n");
|
||||
return LIBLTE_ERROR;
|
||||
|
@ -273,13 +253,16 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32
|
|||
vec_fprint_hex(stdout, data, ra_dl.mcs.tbs);
|
||||
}
|
||||
}
|
||||
if (rnti == SIRNTI && rvidx == 1) {
|
||||
q->pkts_total++;
|
||||
} else if (rnti != SIRNTI) {
|
||||
q->pkts_total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gettimeofday(&t[2], NULL);
|
||||
get_time_interval(t);
|
||||
mean_exec_time = (float) VEC_CMA((float) t[0].tv_usec, mean_exec_time, frame_cnt);
|
||||
|
||||
frame_cnt++;
|
||||
|
||||
|
||||
if (crc_rem == rnti && ret == LIBLTE_SUCCESS) {
|
||||
return ra_dl.mcs.tbs;
|
||||
|
|
|
@ -235,7 +235,7 @@ int ue_mib_sync_and_decode(ue_mib_t * q,
|
|||
}
|
||||
nof_input_frames = nsamples/MIB_FRAME_SIZE_SEARCH;
|
||||
|
||||
for (uint32_t nf=0;nf<nof_input_frames;nf++) {
|
||||
for (int nf=0;nf<nof_input_frames;nf++) {
|
||||
|
||||
/* Find peak and cell id */
|
||||
ret = sync_find(&q->sfind, signal, nf*MIB_FRAME_SIZE_SEARCH, &peak_idx);
|
||||
|
@ -249,10 +249,11 @@ int ue_mib_sync_and_decode(ue_mib_t * q,
|
|||
} else if (ret == 1) {
|
||||
counter4++;
|
||||
}
|
||||
|
||||
int peak_idx_i = (int) peak_idx;
|
||||
/* Check if we have space for reading the MIB and we are in Subframe #0 */
|
||||
if (ret == 1 &&
|
||||
nf*MIB_FRAME_SIZE_SEARCH + peak_idx + MIB_FRAME_SIZE_SEARCH/10 <= nsamples &&
|
||||
nf*MIB_FRAME_SIZE_SEARCH + peak_idx_i + MIB_FRAME_SIZE_SEARCH/10 <= nsamples &&
|
||||
nf*MIB_FRAME_SIZE_SEARCH + peak_idx_i - MIB_FRAME_SIZE_SEARCH/10 >= 0 &&
|
||||
sync_sss_detected(&q->sfind) &&
|
||||
sync_get_sf_idx(&q->sfind) == 0)
|
||||
{
|
||||
|
@ -261,14 +262,12 @@ int ue_mib_sync_and_decode(ue_mib_t * q,
|
|||
&signal[nf*MIB_FRAME_SIZE_SEARCH+peak_idx-MIB_FRAME_SIZE_SEARCH/10],
|
||||
q->bch_payload, &q->nof_tx_ports, &q->sfn_offset);
|
||||
counter3++;
|
||||
} else if ((ret == LIBLTE_SUCCESS && peak_idx != 0) ||
|
||||
(ret == 1 && nf*MIB_FRAME_SIZE_SEARCH + peak_idx + MIB_FRAME_SIZE_SEARCH/10 > nsamples))
|
||||
{
|
||||
printf("Not enough space for PBCH\n",0);
|
||||
ret = MIB_FRAME_UNALIGNED;
|
||||
} else {
|
||||
} else if (ret == 1 && !sync_sss_detected(&q->sfind)) {
|
||||
INFO("SSS not detected\n",0);
|
||||
ret = 0;
|
||||
} else {
|
||||
printf("Not enough space for PBCH\n",0);
|
||||
ret = MIB_FRAME_UNALIGNED;
|
||||
}
|
||||
|
||||
counter1++;
|
||||
|
|
|
@ -62,6 +62,9 @@ LIBLTE_API int bcch_bch_unpack(uint8_t *buffer,
|
|||
lte_cell_t *cell,
|
||||
uint32_t *sfn);
|
||||
|
||||
LIBLTE_API void bcch_bch_fprint(void *bcch_dlsch_msg,
|
||||
FILE *stream);
|
||||
|
||||
LIBLTE_API int bcch_dlsch_pack(void *bcch_dlsch_msg,
|
||||
uint8_t *buffer,
|
||||
uint32_t buffer_size_bytes);
|
||||
|
|
|
@ -113,7 +113,6 @@ int bcch_bch_unpack(uint8_t *buffer, uint32_t msg_nof_bits, lte_cell_t *cell, ui
|
|||
printf("Decoding failed.\n");
|
||||
return LIBLTE_ERROR;
|
||||
}
|
||||
asn_fprint(stdout, &asn_DEF_MasterInformationBlock, req);
|
||||
|
||||
switch(req->dl_Bandwidth) {
|
||||
case MasterInformationBlock__dl_Bandwidth_n6:
|
||||
|
|
Loading…
Reference in New Issue