PDSCH Video demo working

This commit is contained in:
ismagom 2015-01-14 18:16:35 -08:00
parent 40c7db7009
commit 605f102682
17 changed files with 203 additions and 100 deletions

View File

@ -34,24 +34,24 @@ FUNCTION(BuildMex)
cmake_parse_arguments(BuildMex "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (MATLAB_FOUND)
add_library(${BuildMex_MEXNAME}-mat SHARED ${BuildMex_SOURCES})
target_include_directories(${BuildMex_MEXNAME}-mat PUBLIC ${MATLAB_INCLUDE_DIR})
#target_include_directories(${BuildMex_MEXNAME}-mat PUBLIC ${MATLAB_INCLUDE_DIR})
set_target_properties(${BuildMex_MEXNAME}-mat PROPERTIES
SUFFIX "${MATLAB_MEX_EXTENSION}"
PREFIX "liblte_"
OUTPUT_NAME "${BuildMex_MEXNAME}"
COMPILE_FLAGS "-fvisibility=default ${MATLAB_MEX_CFLAGS}"
COMPILE_FLAGS "-fvisibility=default ${MATLAB_MEX_CFLAGS} -I${MATLAB_INCLUDE_DIR}"
)
target_link_libraries(${BuildMex_MEXNAME}-mat ${BuildMex_LIBRARIES} ${MATLAB_MEX_LIBRARY})
install(TARGETS ${BuildMex_MEXNAME}-mat DESTINATION "${MEX_DIR}/liblte/")
endif(MATLAB_FOUND)
if (OCTAVE_FOUND)
add_library(${BuildMex_MEXNAME}-oct SHARED ${BuildMex_SOURCES})
target_include_directories(${BuildMex_MEXNAME}-oct PUBLIC ${OCTAVE_INCLUDE_DIR})
#target_include_directories(${BuildMex_MEXNAME}-oct PUBLIC ${OCTAVE_INCLUDE_DIR})
set_target_properties(${BuildMex_MEXNAME}-oct PROPERTIES
SUFFIX ".${OCTAVE_MEXFILE_EXT}"
PREFIX "liblte_"
OUTPUT_NAME "${BuildMex_MEXNAME}"
COMPILE_FLAGS "-fvisibility=default ${OCTAVE_MEX_CFLAGS} -DUNDEF_BOOL"
COMPILE_FLAGS "-fvisibility=default ${OCTAVE_MEX_CFLAGS} -DUNDEF_BOOL -I${OCTAVE_INCLUDE_DIR}"
)
target_link_libraries(${BuildMex_MEXNAME}-oct ${BuildMex_LIBRARIES} ${OCTAVE_LIBRARIES})
install(TARGETS ${BuildMex_MEXNAME}-oct DESTINATION "${MEX_DIR}/liblte/")

View File

@ -36,6 +36,8 @@
//#define METADATA_VERBOSE
//#define HIDE_MESSAGES
void my_handler(uhd::msg::type_t type, const std::string & msg)
{
//handle the message...
@ -124,8 +126,10 @@ int cuhd_open(char *args, void **h)
// handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=50000000" + ", num_recv_frames=512");
handler->usrp->set_clock_source("internal");
#ifdef HIDE_MESSAGES
uhd::msg::register_handler(my_handler);
#endif
std::string otw, cpu;
otw = "sc16";
cpu = "fc32";

View File

@ -60,12 +60,12 @@ lte_cell_t cell = {
int net_port = -1; // -1 generates random data
uint32_t cfi=1;
uint32_t cfi=2;
uint32_t mcs_idx = 1, last_mcs_idx = 1;
int nof_frames = -1;
char *uhd_args = "";
float uhd_amp = 0.1, uhd_gain = 70.0, uhd_freq = 2400000000;
float uhd_amp = 0.03, uhd_gain = 70.0, uhd_freq = 2400000000;
bool null_file_sink=false;
filesink_t fsink;
@ -303,12 +303,13 @@ reverse(register unsigned int x)
uint32_t prbset_to_bitmask() {
uint32_t mask=0;
for (int i=0;i<cell.nof_prb;i++) {
int nb = (int) ceilf((float) cell.nof_prb / ra_type0_P(cell.nof_prb));
for (int i=0;i<nb;i++) {
if (i >= prbset_orig && i < prbset_orig + prbset_num) {
mask = mask | (0x1<<i);
}
}
return reverse(mask)>>(32-cell.nof_prb);
return reverse(mask)>>(32-nb);
}
int update_radl() {
@ -324,10 +325,11 @@ int update_radl() {
ra_prb_get_dl(&prb_alloc, &ra_dl, cell.nof_prb);
ra_prb_get_re_dl(&prb_alloc, cell.nof_prb, 1, cell.nof_prb<10?(cfi+1):cfi, CPNORM);
ra_mcs_from_idx_dl(mcs_idx, cell.nof_prb, &ra_dl.mcs);
ra_mcs_from_idx_dl(mcs_idx, prb_alloc.slot[0].nof_prb, &ra_dl.mcs);
ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb);
pdsch_harq_reset(&harq_process);
if (pdsch_harq_setup(&harq_process, ra_dl.mcs, &prb_alloc)) {
fprintf(stderr, "Error configuring HARQ process\n");
return -1;
@ -355,7 +357,7 @@ int update_control() {
if(input[0] == 27) {
switch(input[2]) {
case RIGHT_KEY:
if (prbset_orig + prbset_num < cell.nof_prb)
if (prbset_orig + prbset_num < (int) ceilf((float) cell.nof_prb / ra_type0_P(cell.nof_prb)))
prbset_orig++;
break;
case LEFT_KEY:
@ -363,7 +365,7 @@ int update_control() {
prbset_orig--;
break;
case UP_KEY:
if (prbset_num < cell.nof_prb)
if (prbset_num < (int) ceilf((float) cell.nof_prb / ra_type0_P(cell.nof_prb)))
prbset_num++;
break;
case DOWN_KEY:
@ -372,6 +374,7 @@ int update_control() {
prbset_num--;
break;
}
printf("num: %d, orig: %d\n", prbset_num, prbset_orig);
} else {
last_mcs_idx = mcs_idx;
mcs_idx = atoi(input);
@ -408,7 +411,7 @@ void *net_thread_fnc(void *arg) {
if (n > 0) {
int nbytes = 1+(ra_dl.mcs.tbs-1)/8;
rpm += n;
printf("received %d bytes. rpm=%d/%d\n",n,rpm,nbytes);
INFO("received %d bytes. rpm=%d/%d\n",n,rpm,nbytes);
wpm = 0;
while (rpm >= nbytes) {
// wait for packet to be transmitted
@ -423,7 +426,9 @@ void *net_thread_fnc(void *arg) {
INFO("%d bytes left in buffer for next packet\n", rpm);
memcpy(data_unpacked, &data_unpacked[wpm], rpm * sizeof(uint8_t));
}
} else if (n < 0) {
} else if (n == 0) {
rpm = 0;
} else {
fprintf(stderr, "Error receiving from network\n");
exit(-1);
}
@ -441,7 +446,7 @@ int main(int argc, char **argv) {
cf_t *sf_symbols[MAX_PORTS];
cf_t *slot1_symbols[MAX_PORTS];
dci_msg_t dci_msg;
dci_location_t locations[NSUBFRAMES_X_FRAME][10];
dci_location_t locations[NSUBFRAMES_X_FRAME][30];
uint32_t sfn;
chest_dl_t est;
@ -462,8 +467,8 @@ int main(int argc, char **argv) {
cell.phich_resources = R_1;
sfn = 0;
prbset_num = cell.nof_prb;
last_prbset_num = cell.nof_prb;
prbset_num = (int) ceilf((float) cell.nof_prb / ra_type0_P(cell.nof_prb));
last_prbset_num = prbset_num;
/* this *must* be called after setting slot_len_* */
base_init();
@ -506,7 +511,8 @@ int main(int argc, char **argv) {
/* Initiate valid DCI locations */
for (i=0;i<NSUBFRAMES_X_FRAME;i++) {
pdcch_ue_locations(&pdcch, locations[i], 10, i, cfi, 1234);
pdcch_ue_locations(&pdcch, locations[i], 30, i, cfi, 1234);
}
nf = 0;

View File

@ -47,7 +47,7 @@
#include "cuhd_utils.h"
#endif
#define STDOUT_COMPACT
//#define STDOUT_COMPACT
#ifndef DISABLE_GRAPHICS
#include "liblte/graphics/plot.h"
@ -215,19 +215,20 @@ ue_dl_t ue_dl;
ue_sync_t ue_sync;
prog_args_t prog_args;
uint32_t sfn = 0; // system frame number
cf_t *sf_buffer;
netsink_t net_sink, net_sink_signal;
int main(int argc, char **argv) {
int ret;
cf_t *sf_buffer;
lte_cell_t cell;
int64_t sf_cnt;
ue_mib_t ue_mib;
void *uhd;
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;
netsink_t net_sink, net_sink_signal;
parse_args(&prog_args, argc, argv);
@ -236,12 +237,14 @@ int main(int argc, char **argv) {
fprintf(stderr, "Error initiating UDP socket to %s:%d\n", prog_args.net_address, prog_args.net_port);
exit(-1);
}
netsink_set_nonblocking(&net_sink);
}
if (prog_args.net_port_signal > 0) {
if (netsink_init(&net_sink_signal, prog_args.net_address_signal, prog_args.net_port_signal, NETSINK_UDP)) {
fprintf(stderr, "Error initiating UDP socket to %s:%d\n", prog_args.net_address_signal, prog_args.net_port_signal);
exit(-1);
}
netsink_set_nonblocking(&net_sink_signal);
}
#ifndef DISABLE_UHD
@ -351,14 +354,7 @@ int main(int argc, char **argv) {
if (ret < 0) {
fprintf(stderr, "Error calling ue_sync_work()\n");
}
if (prog_args.net_port_signal > 0) {
if (netsink_write(&net_sink_signal, sf_buffer, ue_sync_sf_len(&ue_sync)) < 0) {
fprintf(stderr, "Error sending data through UDP socket\n");
perror("write");
}
}
/* ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */
if (ret == 1) {
switch (state) {
@ -403,7 +399,7 @@ int main(int argc, char **argv) {
if (prog_args.net_port > 0) {
bit_unpack_vector(data_packed, data, n);
if (netsink_write(&net_sink, data, 1+(n-1)/8) < 0) {
fprintf(stderr, "Error sending data through UDP socket\n");
fprintf(stderr, "Error sending data through socket\n");
}
}
}
@ -411,31 +407,38 @@ int main(int argc, char **argv) {
rsrq = VEC_EMA(chest_dl_get_rsrq(&ue_dl.chest), rsrq, 0.05);
rsrp = VEC_EMA(chest_dl_get_rsrp(&ue_dl.chest), rsrp, 0.05);
snr = VEC_EMA(chest_dl_get_snr(&ue_dl.chest), snr, 0.05);
snr = VEC_EMA(chest_dl_get_snr(&ue_dl.chest), snr, 0.01);
nframes++;
if (isnan(rsrq)) {
rsrq = 0;
}
if (isnan(snr)) {
snr = 0;
}
if (isnan(rsrp)) {
rsrp = 0;
}
}
if (ue_sync_get_sfidx(&ue_sync) != 5 && ue_sync_get_sfidx(&ue_sync) != 0) {
pdcch_tx++;
}
// Plot and Printf
if (ue_sync_get_sfidx(&ue_sync) == 5) {
#ifdef STDOUT_COMPACT
printf("SFN: %4d, PDCCH-Miss: %5.2f%% (%d), PDSCH-BLER: %5.2f%% (%d blocks)\r",
sfn, 100*(1-(float) ue_dl.nof_pdcch_detected/nof_trials),ue_dl.nof_pdcch_detected-pdcch_tx,
(float) 100*ue_dl.pkt_errors/ue_dl.pkts_total,nof_trials, ue_dl.pkts_total);
printf("SFN: %4d, PDCCH-Miss: %5.2f%% (%d missed), PDSCH-BLER: %5.2f%% (%d errors)\r",
sfn, 100*(1-(float) ue_dl.nof_pdcch_detected/nof_trials),pdcch_tx-ue_dl.nof_pdcch_detected,
(float) 100*ue_dl.pkt_errors/ue_dl.pkts_total,ue_dl.pkt_errors);
#else
printf("CFO: %+8.4f KHz, SFO: %+8.4f Khz, "
"RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %4.1f dB, "
"PDCCH-Miss: %5.2f%%, PDSCH-BLER: %5.2f%% (%d blocks)\r",
"PDCCH-Miss: %5.2f%% (%d missed), PDSCH-BLER: %5.2f%% (%d errors)\r",
ue_sync_get_cfo(&ue_sync)/1000, ue_sync_get_sfo(&ue_sync)/1000,
10*log10(rsrp*1000)-gain_offset,
10*log10(rsrq), 10*log10(snr),
100*(1-(float) ue_dl.nof_pdcch_detected/nof_trials),
(float) 100*ue_dl.pkt_errors/ue_dl.pkts_total,nof_trials, ue_dl.pkts_total);
100*(1-(float) ue_dl.nof_pdcch_detected/nof_trials), pdcch_tx-ue_dl.nof_pdcch_detected,
(float) 100*ue_dl.pkt_errors/ue_dl.pkts_total, ue_dl.pkt_errors);
#endif
}
@ -447,6 +450,7 @@ int main(int argc, char **argv) {
sfn = 0;
}
}
#ifndef DISABLE_GRAPHICS
if (!prog_args.disable_plots) {
plot_sf_idx = ue_sync_get_sfidx(&ue_sync);
@ -488,7 +492,7 @@ int main(int argc, char **argv) {
#ifndef DISABLE_GRAPHICS
plot_waterfall_t poutfft;
//plot_waterfall_t poutfft;
plot_real_t p_sync, pce;
plot_scatter_t pscatequal, pscatequal_pdcch;
@ -516,9 +520,9 @@ void *plot_thread_run(void *arg) {
tmp_plot2[i] = -80;
}
}
for (i=0;i<CP_NSYMB(ue_dl.cell.cp);i++) {
plot_waterfall_appendNewData(&poutfft, &tmp_plot[i*RE_X_RB*ue_dl.cell.nof_prb], RE_X_RB*ue_dl.cell.nof_prb);
}
//for (i=0;i<CP_NSYMB(ue_dl.cell.cp);i++) {
// plot_waterfall_appendNewData(&poutfft, &tmp_plot[i*RE_X_RB*ue_dl.cell.nof_prb], RE_X_RB*ue_dl.cell.nof_prb);
//}
plot_real_setNewData(&pce, tmp_plot2, REFSIGNAL_NUM_SF(ue_dl.cell.nof_prb,0));
if (!prog_args.input_file_name) {
int max = vec_max_fi(ue_sync.strack.pss.conv_output_avg, ue_sync.strack.pss.frame_size+ue_sync.strack.pss.fft_size-1);
@ -533,6 +537,17 @@ void *plot_thread_run(void *arg) {
plot_scatter_setNewData(&pscatequal, ue_dl.pdsch.pdsch_d, nof_symbols);
plot_scatter_setNewData(&pscatequal_pdcch, ue_dl.pdcch.pdcch_d, 36*ue_dl.pdcch.nof_cce);
if (plot_sf_idx == 1) {
if (prog_args.net_port_signal > 0) {
if (netsink_write(&net_sink_signal, &sf_buffer[ue_sync_sf_len(&ue_sync)/7],
ue_sync_sf_len(&ue_sync)) < 0)
{
fprintf(stderr, "Error sending data through UDP socket\n");
perror("write");
}
}
}
}
return NULL;
@ -542,9 +557,9 @@ void init_plots() {
plot_init();
plot_waterfall_init(&poutfft, RE_X_RB * ue_dl.cell.nof_prb, 1000);
plot_waterfall_setTitle(&poutfft, "Output FFT - Magnitude");
plot_waterfall_setPlotYAxisScale(&poutfft, -40, 40);
//plot_waterfall_init(&poutfft, RE_X_RB * ue_dl.cell.nof_prb, 1000);
//plot_waterfall_setTitle(&poutfft, "Output FFT - Magnitude");
//plot_waterfall_setPlotYAxisScale(&poutfft, -40, 40);
plot_real_init(&pce);
plot_real_setTitle(&pce, "Channel Response - Magnitude");

View File

@ -34,17 +34,20 @@
#include <arpa/inet.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include "liblte/config.h"
typedef enum {NETSINK_UDP, NETSINK_TCP} netsink_type_t;
/* Low-level API */
typedef struct LIBLTE_API {
int sockfd;
bool connected;
netsink_type_t type;
struct sockaddr_in servaddr;
}netsink_t;
typedef enum {NETSINK_UDP, NETSINK_TCP} netsink_type_t;
LIBLTE_API int netsink_init(netsink_t *q,
char *address,
int port,
@ -56,6 +59,8 @@ LIBLTE_API int netsink_write(netsink_t *q,
void *buffer,
int nof_bytes);
LIBLTE_API int netsink_set_nonblocking(netsink_t *q);
/* High-level API */
typedef struct LIBLTE_API {

View File

@ -43,7 +43,7 @@
#include "liblte/phy/phch/dci.h"
#include "liblte/phy/phch/regs.h"
#define TDEC_MAX_ITERATIONS 6
#define TDEC_MAX_ITERATIONS 5
typedef _Complex float cf_t;

View File

@ -43,7 +43,7 @@ typedef _Complex float cf_t;
#define VEC_CMA(data, average, n) ((average) + ((data) - (average)) / ((n)+1))
// Exponential moving average
#define VEC_EMA(data, average, alpha) (average)==0?(data):((alpha)*(data)+(1-alpha)*(average))
#define VEC_EMA(data, average, alpha) ((alpha)*(data)+(1-alpha)*(average))
/** Return the sum of all the elements */
LIBLTE_API int vec_acc_ii(int *x, uint32_t len);

View File

@ -43,6 +43,8 @@
#define CHEST_RS_AVERAGE_TIME 2
#define CHEST_RS_AVERAGE_FREQ 3
#define NOISE_POWER_USE_ESTIMATES
/** 3GPP LTE Downlink channel estimator and equalizer.
* Estimates the channel in the resource elements transmitting references and interpolates for the rest
@ -115,15 +117,14 @@ int chest_dl_init(chest_dl_t *q, lte_cell_t cell)
}
/* Set default time/freq filters */
float f[3]={0.1, 0.8, 0.1};
chest_dl_set_filter_freq(q, f, 3);
//float f[3]={0.1, 0.8, 0.1};
//chest_dl_set_filter_freq(q, f, 3);
//float f[5]={0.05, 0.15, 0.6, 0.15, 0.05};
//chest_dl_set_filter_freq(q, f, 5);
float f[5]={0.05, 0.15, 0.6, 0.15, 0.05};
chest_dl_set_filter_freq(q, f, 5);
//float t[2]={0.1, 0.9};
float t[1] = {1.0};
chest_dl_set_filter_time(q, t, 1);
float t[2]={0.15, 0.85};
chest_dl_set_filter_time(q, t, 2);
q->cell = cell;
}
@ -194,6 +195,10 @@ int chest_dl_set_filter_time(chest_dl_t *q, float *filter, uint32_t filter_len)
}
#ifdef NOISE_POWER_USE_ESTIMATES
/* Uses the difference between the averaged and non-averaged pilot estimates */
static float estimate_noise_port(chest_dl_t *q, uint32_t port_id, cf_t *avg_pilots) {
/* Use difference between averaged and noisy LS pilot estimates */
vec_sub_ccc(avg_pilots, q->pilot_estimates[port_id],
@ -202,6 +207,22 @@ static float estimate_noise_port(chest_dl_t *q, uint32_t port_id, cf_t *avg_pilo
return vec_avg_power_cf(q->tmp_noise, REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id));
}
#else
/* Uses the 5 empty transmitted SC before and after the SSS and PSS sequences for noise estimation */
static float estimate_noise_empty_sc(chest_dl_t *q, cf_t *input) {
int k_sss = (CP_NSYMB(q->cell.cp) - 2) * q->cell.nof_prb * RE_X_RB + q->cell.nof_prb * RE_X_RB / 2 - 31;
float noise_power = 0;
noise_power += vec_avg_power_cf(&input[k_sss-5], 5); // 5 empty SC before SSS
noise_power += vec_avg_power_cf(&input[k_sss+62], 5); // 5 empty SC after SSS
int k_pss = (CP_NSYMB(q->cell.cp) - 1) * q->cell.nof_prb * RE_X_RB + q->cell.nof_prb * RE_X_RB / 2 - 31;
noise_power += vec_avg_power_cf(&input[k_pss-5], 5); // 5 empty SC before PSS
noise_power += vec_avg_power_cf(&input[k_pss+62], 5); // 5 empty SC after PSS
return noise_power;
}
#endif
#define pilot_est(idx) q->pilot_estimates[port_id][REFSIGNAL_PILOT_IDX(idx,l,q->cell)]
#define pilot_avg(idx) q->pilot_estimates_average[port_id][REFSIGNAL_PILOT_IDX(idx,l,q->cell)]
#define pilot_tmp(idx) q->tmp_freqavg[REFSIGNAL_PILOT_IDX(idx,l,q->cell)]
@ -227,11 +248,6 @@ static void average_pilots(chest_dl_t *q, uint32_t port_id)
}
}
/* Compute noise estimation before time averaging.
* FIXME: Apparently the noise estimation performance is better with frequency averaging only
*/
q->noise_estimate[port_id] = estimate_noise_port(q, port_id, q->tmp_freqavg);
for (l=0;l<refsignal_cs_nof_symbols(port_id);l++) {
/* Filter in time domain. */
if (q->filter_time_len > 0) {
@ -252,6 +268,10 @@ static void average_pilots(chest_dl_t *q, uint32_t port_id)
memcpy(&pilot_avg(0), &pilot_tmp(0), nref * sizeof(cf_t));
}
}
#ifdef NOISE_POWER_USE_ESTIMATES
q->noise_estimate[port_id] = estimate_noise_port(q, port_id, q->pilot_estimates_average[port_id]);
#endif
}
#define cesymb(i) ce[RE_IDX(q->cell.nof_prb,i,0)]
@ -308,6 +328,8 @@ float chest_dl_rssi(chest_dl_t *q, cf_t *input, uint32_t port_id) {
return rssi/nsymbols;
}
//#define RSRP_FROM_ESTIMATES
float chest_dl_rsrp(chest_dl_t *q, uint32_t port_id) {
#ifdef RSRP_FROM_ESTIMATES
return vec_avg_power_cf(q->pilot_estimates[port_id],
@ -341,7 +363,10 @@ int chest_dl_estimate_port(chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx
if (ce != NULL) {
interpolate_pilots(q, ce, port_id);
}
#ifndef NOISE_POWER_USE_ESTIMATES
q->noise_estimate[port_id] = estimate_noise_empty_sc(q, input);
#endif
return 0;
}
@ -361,7 +386,11 @@ float chest_dl_get_noise_estimate(chest_dl_t *q) {
float chest_dl_get_snr(chest_dl_t *q) {
// Uses RSRP as an estimation of the useful signal power
return chest_dl_get_rsrp(q)/chest_dl_get_noise_estimate(q);
#ifdef NOISE_POWER_USE_ESTIMATES
return chest_dl_get_rsrp(q)/chest_dl_get_noise_estimate(q)/sqrt(2*lte_symbol_sz(q->cell.nof_prb));
#else
return chest_dl_get_rsrp(q)/chest_dl_get_noise_estimate(q)/sqrt(2);
#endif
}
float chest_dl_get_rssi(chest_dl_t *q) {

View File

@ -196,7 +196,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
}
/* Loop through the 10 subframes */
if (chest_dl_estimate(&chest, input_signal, ce, sf_idx)) {
if (chest_dl_estimate(&chest, input_signal, ce, sf_idx)) {
mexErrMsgTxt("Error running channel estimator\n");
return;
}
@ -244,7 +244,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
}
if (nlhs >= 4) {
plhs[3] = mxCreateDoubleScalar(chest_dl_get_snr(&chest));
plhs[3] = mxCreateDoubleScalar(chest_dl_get_noise_estimate(&chest));
}
return;

View File

@ -33,6 +33,8 @@
#include <stdlib.h>
#include <math.h>
#include <strings.h>
#include <errno.h>
#include <fcntl.h>
#include "liblte/phy/io/netsink.h"
@ -40,8 +42,7 @@
int netsink_init(netsink_t *q, char *address, int port, netsink_type_t type) {
bzero(q, sizeof(netsink_t));
q->sockfd=socket(AF_INET, type==NETSINK_TCP?SOCK_STREAM:SOCK_DGRAM,0);
q->sockfd=socket(AF_INET, type==NETSINK_TCP?SOCK_STREAM:SOCK_DGRAM,0);
if (q->sockfd < 0) {
perror("socket");
return -1;
@ -50,13 +51,9 @@ int netsink_init(netsink_t *q, char *address, int port, netsink_type_t type) {
q->servaddr.sin_family = AF_INET;
q->servaddr.sin_addr.s_addr=inet_addr(address);
q->servaddr.sin_port=htons(port);
q->connected = false;
q->type = type;
printf("Connecting to %s:%d\n", address, port);
if (connect(q->sockfd,&q->servaddr,sizeof(q->servaddr)) < 0) {
perror("connect");
return -1;
}
return 0;
}
@ -67,8 +64,45 @@ void netsink_free(netsink_t *q) {
bzero(q, sizeof(netsink_t));
}
int netsink_set_nonblocking(netsink_t *q) {
if (fcntl(q->sockfd, F_SETFL, O_NONBLOCK)) {
perror("fcntl");
return -1;
}
return 0;
}
int netsink_write(netsink_t *q, void *buffer, int nof_bytes) {
return write(q->sockfd, buffer, nof_bytes);
if (!q->connected) {
if (connect(q->sockfd,&q->servaddr,sizeof(q->servaddr)) < 0) {
if (errno == ECONNREFUSED || errno == EINPROGRESS) {
return 0;
} else {
perror("connect");
exit(-1);
return -1;
}
} else {
q->connected = true;
}
}
int n = 0;
if (q->connected) {
n = write(q->sockfd, buffer, nof_bytes);
if (n < 0) {
if (errno == ECONNRESET) {
close(q->sockfd);
q->sockfd=socket(AF_INET, q->type==NETSINK_TCP?SOCK_STREAM:SOCK_DGRAM,0);
if (q->sockfd < 0) {
perror("socket");
return -1;
}
q->connected = false;
return 0;
}
}
}
return n;
}

View File

@ -93,15 +93,14 @@ int netsource_read(netsource_t *q, void *buffer, int nbytes) {
}
}
int n = read(q->connfd, buffer, nbytes);
if (n == 0) {
printf("Connection closed\n");
close(q->connfd);
q->connfd = 0;
return 0;
}
if (n == -1) {
if (errno == ECONNRESET) {
printf("Connection closed\n");
close(q->connfd);
q->connfd = 0;
return 0;
} else {
perror("read");
}
perror("read");
}
return n;
}

View File

@ -435,7 +435,6 @@ int pdcch_extract_llr(pdcch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float n
static void crc_set_mask_rnti(uint8_t *crc, uint16_t rnti) {
uint32_t i;
uint8_t mask[16];

View File

@ -338,7 +338,7 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input, float *corr_peak_value)
int pl_lb;
if (corr_peak_pos > 0) {
pl_lb = corr_peak_pos-1;
while(q->conv_output_avg[pl_lb-1] <= q->conv_output_avg[pl_lb] && pl_lb > 1) {
while(q->conv_output_avg[pl_lb-1] <= q->conv_output_avg[pl_lb] && pl_lb > 1) {
pl_lb --;
}
} else {

View File

@ -217,6 +217,10 @@ int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, ui
nof_locations = pdcch_ue_locations(&q->pdcch, locations, MAX_CANDIDATES, sf_idx, cfi, q->current_rnti);
formats = ue_formats;
nof_formats = nof_ue_formats;
if (q->current_rnti == 1234) {
nof_locations = 1;
nof_formats = 1;
}
}
/* Extract all PDCCH symbols and get LLRs */
@ -256,7 +260,7 @@ int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, ui
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);
&q->harq_process[0], rvidx);
if (ret == LIBLTE_ERROR) {
q->pkt_errors++;
} else if (ret == LIBLTE_ERROR_INVALID_INPUTS) {
@ -280,7 +284,7 @@ int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, ui
mean_exec_time = (float) VEC_EMA((float) t[0].tv_usec, mean_exec_time, 0.01);
if (found_dci > 0 && ret == LIBLTE_SUCCESS) {
if (found_dci > 0 && ret == LIBLTE_SUCCESS) {
return ra_dl.mcs.tbs;
} else {
return 0;

View File

@ -259,6 +259,7 @@ static int find_peak_ok(ue_sync_t *q) {
q->frame_no_cnt = 0;
q->frame_total_cnt = 0;
q->frame_find_cnt = 0;
q->mean_time_offset = 0;
/* Set tracking CFO average to find CFO */
q->strack.mean_cfo = q->sfind.mean_cfo;
@ -289,10 +290,13 @@ static int track_peak_ok(ue_sync_t *q, uint32_t track_idx) {
INFO("Time offset adjustment: %d samples\n", q->time_offset);
}
/* compute cumulative moving average time offset */
q->mean_time_offset = (float) VEC_CMA((float) q->time_offset, q->mean_time_offset, q->frame_total_cnt);
/* If the PSS peak is beyond the frame (we sample too slowly),
discard the offseted samples to align next frame */
if (q->time_offset > 0 && q->time_offset < MAX_TIME_OFFSET) {
INFO("Positive time offset %d samples. Adjusting now.\n", q->time_offset);
INFO("\nPositive time offset %d samples. Mean time offset %f.\n", q->time_offset, q->mean_time_offset);
if (q->recv_callback(q->stream, dummy, (uint32_t) q->time_offset) < 0) {
fprintf(stderr, "Error receiving from USRP\n");
return LIBLTE_ERROR;
@ -300,9 +304,6 @@ static int track_peak_ok(ue_sync_t *q, uint32_t track_idx) {
q->time_offset = 0;
}
/* compute cumulative moving average time offset */
q->mean_time_offset = (float) VEC_CMA((float) q->time_offset, q->mean_time_offset, q->frame_total_cnt);
q->peak_idx = q->sf_len/2 + q->time_offset;
q->frame_ok_cnt++;
q->frame_no_cnt = 0;
@ -335,7 +336,6 @@ static int receive_samples(ue_sync_t *q) {
q->time_offset = -q->time_offset;
}
INFO("Receiving %d samples\n", q->frame_len - q->time_offset);
/* Get N subframes from the USRP getting more samples and keeping the previous samples, if any */
if (q->recv_callback(q->stream, &q->input_buffer[q->time_offset], q->frame_len - q->time_offset) < 0) {
return LIBLTE_ERROR;
@ -450,6 +450,7 @@ int ue_sync_get_buffer(ue_sync_t *q, cf_t **sf_symbols) {
q->input_buffer,
q->input_buffer,
-sync_get_cfo(&q->strack) / q->fft_size);
}
*sf_symbols = q->input_buffer;

View File

@ -14,7 +14,7 @@ postEVM_liblte = zeros(length(SNR_values_db),Nrealizations);
enb.NDLRB = 6; % Number of resource blocks
enb.CellRefP = 2; % One transmit antenna port
enb.CellRefP = 1; % One transmit antenna port
enb.NCellID = 0; % Cell ID
enb.CyclicPrefix = 'Normal'; % Normal cyclic prefix
enb.DuplexMode = 'FDD'; % FDD
@ -101,6 +101,8 @@ for sf = 0:10
end
txGrid([1:5 68:72],6:7) = zeros(10,2);
%% OFDM Modulation
[txWaveform,info] = lteOFDMModulate(enb,txGrid);
@ -118,7 +120,7 @@ SNR = 10^(SNRdB/20); % Linear SNR
cfg.SamplingRate = info.SamplingRate;
% Pass data through the fading channel model
rxWaveform = lteFadingChannel(cfg,txWaveform);
%rxWaveform = lteFadingChannel(cfg,txWaveform);
rxWaveform = txWaveform;
%% Additive Noise
@ -149,14 +151,19 @@ addpath('../../debug/lte/phy/lib/ch_estimation/test')
[estChannel, noiseEst(snr_idx)] = lteDLChannelEstimate(enb,cec,rxGrid);
output=[];
snrest = zeros(10,1);
for i=0:9
nulls = rxGrid([1:5 68:72],6:7);
noiseEst(snr_idx) = var(nulls(:));
%for i=0:9
i=0;
% if (SNR_values_db(snr_idx) < 25)
[d, a, out, snrest(i+1)] = liblte_chest(enb.NCellID,enb.CellRefP,rxGrid(:,i*14+1:(i+1)*14),[0.15 0.7 0.15],[],i);
[d, a, out, snrest(i+1)] = liblte_chest(enb.NCellID,enb.CellRefP,rxGrid(:,i*14+1:(i+1)*14),[0.1 0.8 0.1],[0.1 0.9],i);
% else
% [d, a, out, snrest(i+1)] = liblte_chest(enb.NCellID,enb.CellRefP,rxGrid(:,i*14+1:(i+1)*14),[0.05 0.9 0.05],[],i);
% end
output = [output out];
end
%end
SNRest(snr_idx)=mean(snrest);
disp(10*log10(SNRest(snr_idx)))
%% MMSE Equalization
@ -196,8 +203,8 @@ end
%
% subplot(1,2,2)
%SNR_liblte = 1./(SNRest*sqrt(2.0*enb.CellRefP*double(info.Nfft)));
SNR_liblte = SNRest;
SNR_matlab = 1./(noiseEst*sqrt(2.0*enb.CellRefP*double(info.Nfft)));
SNR_liblte = 1./(SNRest*sqrt(2.0));
SNR_matlab = 1./(noiseEst*sqrt(2.0));
plot(SNR_values_db, SNR_values_db, SNR_values_db, 10*log10(SNR_liblte),SNR_values_db, 10*log10(SNR_matlab))
%plot(SNR_values_db, 10*log10(noiseTx), SNR_values_db, 10*log10(SNRest),SNR_values_db, 10*log10(noiseEst))

View File

@ -50,10 +50,10 @@ IF (MATLAB_FOUND OR OCTAVE_FOUND)
INSTALL(TARGETS liblte_mex DESTINATION ${LIBRARY_DIR})
LIBLTE_SET_PIC(liblte_mex)
if (MATLAB_FOUND)
target_include_directories(liblte_mex PUBLIC ${MATLAB_INCLUDE_DIR})
include_directories(${MATLAB_INCLUDE_DIR})
endif(MATLAB_FOUND)
if (OCTAVE_FOUND)
target_include_directories(liblte_mex PUBLIC ${OCTAVE_INCLUDE_DIR})
include_directories(${OCTAVE_INCLUDE_DIR})
endif (OCTAVE_FOUND)
ELSEIF (MATLAB_FOUND OR OCTAVE_FOUND)