From 6fc9c96c58b7856c3a23ec87a3ceccd0a0e3129f Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 28 Feb 2018 12:02:17 +0100 Subject: [PATCH 01/70] Added CSI softbits weightening for Single antenna transmission --- lib/include/srslte/phy/mimo/precoding.h | 3 + lib/include/srslte/phy/phch/pdsch.h | 6 ++ lib/include/srslte/phy/utils/simd.h | 12 +++- .../phy/ch_estimation/test/chest_test_dl.c | 4 +- lib/src/phy/mimo/precoding.c | 58 +++++++++++++++++-- lib/src/phy/mimo/test/precoder_test.c | 2 +- lib/src/phy/phch/pbch.c | 2 +- lib/src/phy/phch/pcfich.c | 2 +- lib/src/phy/phch/pdcch.c | 2 +- lib/src/phy/phch/pdsch.c | 52 ++++++++++++++++- lib/src/phy/phch/phich.c | 2 +- lib/src/phy/phch/pmch.c | 2 +- lib/src/phy/phch/pucch.c | 2 +- lib/src/phy/phch/pusch.c | 2 +- 14 files changed, 135 insertions(+), 16 deletions(-) diff --git a/lib/include/srslte/phy/mimo/precoding.h b/lib/include/srslte/phy/mimo/precoding.h index f8463d1cb..27395085c 100644 --- a/lib/include/srslte/phy/mimo/precoding.h +++ b/lib/include/srslte/phy/mimo/precoding.h @@ -79,6 +79,7 @@ SRSLTE_API int srslte_precoding_type(cf_t *x[SRSLTE_MAX_LAYERS], SRSLTE_API int srslte_predecoding_single(cf_t *y, cf_t *h, cf_t *x, + float *csi, int nof_symbols, float scaling, float noise_estimate); @@ -86,6 +87,7 @@ SRSLTE_API int srslte_predecoding_single(cf_t *y, SRSLTE_API int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, + float *csi, int nof_rxant, int nof_symbols, float scaling, @@ -111,6 +113,7 @@ SRSLTE_API void srslte_predecoding_set_mimo_decoder (srslte_mimo_decoder_t _mimo SRSLTE_API int srslte_predecoding_type(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], + float *csi, int nof_rxant, int nof_ports, int nof_layers, diff --git a/lib/include/srslte/phy/phch/pdsch.h b/lib/include/srslte/phy/phch/pdsch.h index dab900d77..1889078e6 100644 --- a/lib/include/srslte/phy/phch/pdsch.h +++ b/lib/include/srslte/phy/phch/pdsch.h @@ -76,6 +76,9 @@ typedef struct SRSLTE_API { cf_t *d[SRSLTE_MAX_CODEWORDS]; /* Modulated/Demodulated codewords */ void *e[SRSLTE_MAX_CODEWORDS]; + bool csi_enabled; + float *csi[SRSLTE_MAX_CODEWORDS]; /* Channel Strengh Indicator */ + /* tx & rx objects */ srslte_modem_table_t mod[4]; @@ -107,6 +110,9 @@ SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q, SRSLTE_API void srslte_pdsch_set_power_allocation(srslte_pdsch_t *q, float rho_a); +SRSLTE_API int srslte_pdsch_enable_csi(srslte_pdsch_t *q, + bool enable); + SRSLTE_API void srslte_pdsch_free_rnti(srslte_pdsch_t *q, uint16_t rnti); diff --git a/lib/include/srslte/phy/utils/simd.h b/lib/include/srslte/phy/utils/simd.h index e22a9ef09..3b5a00a8a 100644 --- a/lib/include/srslte/phy/utils/simd.h +++ b/lib/include/srslte/phy/utils/simd.h @@ -530,7 +530,7 @@ static inline simd_cf_t srslte_simd_cfi_loadu(const cf_t *ptr) { 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F), in2); #else /* LV_HAVE_AVX512 */ - #ifdef LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX2 __m256 in1 = _mm256_permute_ps(_mm256_loadu_ps((float*)(ptr)), 0b11011000); __m256 in2 = _mm256_permute_ps(_mm256_loadu_ps((float*)(ptr + 4)), 0b11011000); ret.re = _mm256_unpacklo_ps(in1, in2); @@ -705,6 +705,16 @@ static inline void srslte_simd_cf_storeu(float *re, float *im, simd_cf_t simdreg #endif /* LV_HAVE_AVX512 */ } +static inline simd_f_t srslte_simd_cf_re(simd_cf_t in) { + simd_f_t out = in.re; +#ifdef LV_HAVE_AVX2 + /* Permute for AVX registers (mis SSE registers) */ + const __m256i idx = _mm256_setr_epi32(0, 2, 4, 6, 1, 3, 5, 7); + out = _mm256_permutevar8x32_ps(out, idx); +#endif /* LV_HAVE_AVX2 */ + return out; +} + static inline simd_cf_t srslte_simd_cf_set1 (cf_t x) { simd_cf_t ret; #ifdef LV_HAVE_AVX512 diff --git a/lib/src/phy/ch_estimation/test/chest_test_dl.c b/lib/src/phy/ch_estimation/test/chest_test_dl.c index 62f7e1c86..222263c7e 100644 --- a/lib/src/phy/ch_estimation/test/chest_test_dl.c +++ b/lib/src/phy/ch_estimation/test/chest_test_dl.c @@ -173,7 +173,7 @@ int main(int argc, char **argv) { gettimeofday(&t[1], NULL); for (int j=0;j<100;j++) { - srslte_predecoding_single(input, ce, output, num_re, 1.0f, 0); + srslte_predecoding_single(input, ce, output, NULL, num_re, 1.0f, 0); } gettimeofday(&t[2], NULL); get_time_interval(t); @@ -188,7 +188,7 @@ int main(int argc, char **argv) { gettimeofday(&t[1], NULL); for (int j=0;j<100;j++) { - srslte_predecoding_single(input, ce, output, num_re, 1.0f, srslte_chest_dl_get_noise_estimate(&est)); + srslte_predecoding_single(input, ce, output, NULL, num_re, 1.0f, srslte_chest_dl_get_noise_estimate(&est)); } gettimeofday(&t[2], NULL); get_time_interval(t); diff --git a/lib/src/phy/mimo/precoding.c b/lib/src/phy/mimo/precoding.c index 6d50e3ed2..f8faeda75 100644 --- a/lib/src/phy/mimo/precoding.c +++ b/lib/src/phy/mimo/precoding.c @@ -34,6 +34,7 @@ #include "srslte/phy/utils/vector.h" #include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/mat.h" +#include "srslte/phy/utils/simd.h" #ifdef LV_HAVE_SSE #include @@ -252,8 +253,49 @@ int srslte_predecoding_single_gen(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_ return nof_symbols; } +int srslte_predecoding_single_csi(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, float *csi, int nof_rxant, int nof_symbols, float scaling, float noise_estimate) { + int i = 0; + +#if SRSLTE_SIMD_CF_SIZE + const simd_f_t _noise = srslte_simd_f_set1(noise_estimate); + const simd_f_t _scaling = srslte_simd_f_set1(1.0f / scaling); + + for (; i < nof_symbols - SRSLTE_SIMD_CF_SIZE + 1; i += SRSLTE_SIMD_CF_SIZE) { + simd_cf_t _r = srslte_simd_cf_zero(); + simd_f_t _hh = srslte_simd_f_zero(); + + for (int p = 0; p < nof_rxant; p++) { + simd_cf_t _y = srslte_simd_cfi_load(&y[p][i]); + simd_cf_t _h = srslte_simd_cfi_load(&h[p][i]); + + _r = srslte_simd_cf_add(_r, srslte_simd_cf_conjprod(_y, _h)); + _hh = srslte_simd_f_add(_hh, srslte_simd_cf_re(srslte_simd_cf_conjprod(_h, _h))); + } + + simd_f_t _csi = srslte_simd_f_add(_hh, _noise); + simd_cf_t _x = srslte_simd_cf_mul(srslte_simd_cf_mul(_r, _scaling), srslte_simd_f_rcp(_csi)); + + srslte_simd_f_store(&csi[i], _csi); + srslte_simd_cfi_store(&x[i], _x); + } +#endif + + for (; i < nof_symbols; i++) { + cf_t r = 0; + float hh = 0; + float _scaling = 1.0f / scaling; + for (int p = 0; p < nof_rxant; p++) { + r += y[p][i] * conj(h[p][i]); + hh += (__real__ h[p][i] * __real__ h[p][i]) + (__imag__ h[p][i] * __imag__ h[p][i]); + } + csi[i] = hh + noise_estimate; + x[i] = r * _scaling / csi[i]; + } + return nof_symbols; +} + /* ZF/MMSE SISO equalizer x=y(h'h+no)^(-1)h' (ZF if n0=0.0)*/ -int srslte_predecoding_single(cf_t *y_, cf_t *h_, cf_t *x, int nof_symbols, float scaling, float noise_estimate) { +int srslte_predecoding_single(cf_t *y_, cf_t *h_, cf_t *x, float *csi, int nof_symbols, float scaling, float noise_estimate) { cf_t *y[SRSLTE_MAX_PORTS]; cf_t *h[SRSLTE_MAX_PORTS]; @@ -261,6 +303,10 @@ int srslte_predecoding_single(cf_t *y_, cf_t *h_, cf_t *x, int nof_symbols, floa h[0] = h_; int nof_rxant = 1; + if (csi) { + return srslte_predecoding_single_csi(y, h, x, csi, nof_rxant, nof_symbols, scaling, noise_estimate); + } + #ifdef LV_HAVE_AVX if (nof_symbols > 32 && nof_rxant <= 2) { return srslte_predecoding_single_avx(y, h, x, nof_rxant, nof_symbols, scaling, noise_estimate); @@ -281,8 +327,12 @@ int srslte_predecoding_single(cf_t *y_, cf_t *h_, cf_t *x, int nof_symbols, floa } /* ZF/MMSE SISO equalizer x=y(h'h+no)^(-1)h' (ZF if n0=0.0)*/ -int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, +int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, float *csi, int nof_rxant, int nof_symbols, float scaling, float noise_estimate) { + if (csi) { + return srslte_predecoding_single_csi(y, h, x, csi, nof_rxant, nof_symbols, scaling, noise_estimate); + } + #ifdef LV_HAVE_AVX if (nof_symbols > 32) { return srslte_predecoding_single_avx(y, h, x, nof_rxant, nof_symbols, scaling, noise_estimate); @@ -1418,7 +1468,7 @@ void srslte_predecoding_set_mimo_decoder (srslte_mimo_decoder_t _mimo_decoder) { /* 36.211 v10.3.0 Section 6.3.4 */ int srslte_predecoding_type(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], - cf_t *x[SRSLTE_MAX_LAYERS], int nof_rxant, int nof_ports, int nof_layers, + cf_t *x[SRSLTE_MAX_LAYERS], float *csi, int nof_rxant, int nof_ports, int nof_layers, int codebook_idx, int nof_symbols, srslte_mimo_type_t type, float scaling, float noise_estimate) { @@ -1451,7 +1501,7 @@ int srslte_predecoding_type(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS] return -1; case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA: if (nof_ports == 1 && nof_layers == 1) { - return srslte_predecoding_single_multi(y, h[0], x[0], nof_rxant, nof_symbols, scaling, noise_estimate); + return srslte_predecoding_single_multi(y, h[0], x[0], csi, nof_rxant, nof_symbols, scaling, noise_estimate); } else { fprintf(stderr, "Number of ports and layers must be 1 for transmission on single antenna ports (%d, %d)\n", nof_ports, nof_layers); diff --git a/lib/src/phy/mimo/test/precoder_test.c b/lib/src/phy/mimo/test/precoder_test.c index 1054545c3..a6925f318 100644 --- a/lib/src/phy/mimo/test/precoder_test.c +++ b/lib/src/phy/mimo/test/precoder_test.c @@ -291,7 +291,7 @@ int main(int argc, char **argv) { /* predecoding / equalization */ struct timeval t[3]; gettimeofday(&t[1], NULL); - srslte_predecoding_type(r, h, xr, nof_rx_ports, nof_tx_ports, nof_layers, + srslte_predecoding_type(r, h, xr, NULL, nof_rx_ports, nof_tx_ports, nof_layers, codebook_idx, nof_re, type, scaling, powf(10, -snr_db / 10)); gettimeofday(&t[2], NULL); get_time_interval(t); diff --git a/lib/src/phy/phch/pbch.c b/lib/src/phy/phch/pbch.c index c72b12c60..e7c0c33af 100644 --- a/lib/src/phy/phch/pbch.c +++ b/lib/src/phy/phch/pbch.c @@ -497,7 +497,7 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS /* in control channels, only diversity is supported */ if (nant == 1) { /* no need for layer demapping */ - srslte_predecoding_single(q->symbols[0], q->ce[0], q->d, q->nof_symbols, 1.0f, noise_estimate); + srslte_predecoding_single(q->symbols[0], q->ce[0], q->d, NULL, q->nof_symbols, 1.0f, noise_estimate); } else { srslte_predecoding_diversity(q->symbols[0], q->ce, x, nant, q->nof_symbols, 1.0f); diff --git a/lib/src/phy/phch/pcfich.c b/lib/src/phy/phch/pcfich.c index 7269000a8..6b00e768a 100644 --- a/lib/src/phy/phch/pcfich.c +++ b/lib/src/phy/phch/pcfich.c @@ -219,7 +219,7 @@ int srslte_pcfich_decode_multi(srslte_pcfich_t *q, cf_t *sf_symbols[SRSLTE_MAX_P /* in control channels, only diversity is supported */ if (q->cell.nof_ports == 1) { /* no need for layer demapping */ - srslte_predecoding_single_multi(q_symbols, q_ce[0], q->d, q->nof_rx_antennas, q->nof_symbols, 1.0f, noise_estimate); + srslte_predecoding_single_multi(q_symbols, q_ce[0], q->d, NULL, q->nof_rx_antennas, q->nof_symbols, 1.0f, noise_estimate); } else { srslte_predecoding_diversity_multi(q_symbols, q_ce, x, q->nof_rx_antennas, q->cell.nof_ports, q->nof_symbols, 1.0f); srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, q->nof_symbols / q->cell.nof_ports); diff --git a/lib/src/phy/phch/pdcch.c b/lib/src/phy/phch/pdcch.c index 206ef1be6..83f681f8f 100644 --- a/lib/src/phy/phch/pdcch.c +++ b/lib/src/phy/phch/pdcch.c @@ -490,7 +490,7 @@ int srslte_pdcch_extract_llr_multi(srslte_pdcch_t *q, cf_t *sf_symbols[SRSLTE_MA /* in control channels, only diversity is supported */ if (q->cell.nof_ports == 1) { /* no need for layer demapping */ - srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, q->nof_rx_antennas, nof_symbols, 1.0f, noise_estimate/2); + srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, NULL, q->nof_rx_antennas, nof_symbols, 1.0f, noise_estimate/2); } else { srslte_predecoding_diversity_multi(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, nof_symbols, 1.0f); srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, nof_symbols / q->cell.nof_ports); diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 1cf4af4e2..4cfa5c75c 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -294,6 +294,10 @@ void srslte_pdsch_free(srslte_pdsch_t *q) { if (q->d[i]) { free(q->d[i]); } + + if (q->csi[i]) { + free(q->csi[i]); + } } /* Free sch objects */ @@ -394,6 +398,22 @@ void srslte_pdsch_set_power_allocation(srslte_pdsch_t *q, float rho_a) { } } +int srslte_pdsch_enable_csi(srslte_pdsch_t *q, bool enable) { + if (enable) { + for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + if (!q->csi[i]) { + q->csi[i] = srslte_vec_malloc(sizeof(float) * q->max_re); + if (!q->csi[i]) { + return SRSLTE_ERROR; + } + } + } + } + q->csi_enabled = enable; + + return SRSLTE_SUCCESS; +} + void srslte_pdsch_free_rnti(srslte_pdsch_t* q, uint16_t rnti) { uint32_t rnti_idx = q->is_ue?0:rnti; @@ -617,6 +637,36 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c /* Bit scrambling */ srslte_scrambling_s_offset(seq, q->e[codeword_idx], 0, nbits->nof_bits); + uint32_t qm = nbits->nof_bits/nbits->nof_re; + switch(cfg->grant.mcs[tb_idx].mod) { + + case SRSLTE_MOD_BPSK: + qm = 1; + break; + case SRSLTE_MOD_QPSK: + qm = 2; + break; + case SRSLTE_MOD_16QAM: + qm = 4; + break; + case SRSLTE_MOD_64QAM: + qm = 6; + break; + default: + ERROR("No modulation"); + } + + int16_t *e = q->e[codeword_idx]; + + if (q->csi_enabled) { + for (int i = 0; i < nbits->nof_bits / qm; i++) { + float csi = q->csi[codeword_idx][i]; + for (int k = 0; k < qm; k++) { + e[qm * i + k] = (int16_t) ((float) e[qm * i + k] * csi); + } + } + } + /* Return */ ret = srslte_dlsch_decode2(&q->dl_sch, cfg, softbuffer, q->e[codeword_idx], data, tb_idx); @@ -702,7 +752,7 @@ int srslte_pdsch_decode(srslte_pdsch_t *q, } // Pre-decoder - if (srslte_predecoding_type(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers, + if (srslte_predecoding_type(q->symbols, q->ce, x, q->csi[0], q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers, cfg->codebook_idx, cfg->nbits[0].nof_re, cfg->mimo_type, pdsch_scaling, noise_estimate)<0) { DEBUG("Error predecoding\n"); return SRSLTE_ERROR; diff --git a/lib/src/phy/phch/phich.c b/lib/src/phy/phch/phich.c index 6990d69e2..15aa4db88 100644 --- a/lib/src/phy/phch/phich.c +++ b/lib/src/phy/phch/phich.c @@ -239,7 +239,7 @@ int srslte_phich_decode(srslte_phich_t *q, cf_t *sf_symbols[SRSLTE_MAX_PORTS], /* in control channels, only diversity is supported */ if (q->cell.nof_ports == 1) { /* no need for layer demapping */ - srslte_predecoding_single_multi(q_sf_symbols, q_ce[0], q->d0, q->nof_rx_antennas, SRSLTE_PHICH_MAX_NSYMB, 1.0f, noise_estimate); + srslte_predecoding_single_multi(q_sf_symbols, q_ce[0], q->d0, NULL, q->nof_rx_antennas, SRSLTE_PHICH_MAX_NSYMB, 1.0f, noise_estimate); } else { srslte_predecoding_diversity_multi(q_sf_symbols, q_ce, x, q->nof_rx_antennas, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB, 1.0f); srslte_layerdemap_diversity(x, q->d0, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports); diff --git a/lib/src/phy/phch/pmch.c b/lib/src/phy/phch/pmch.c index c1c322f34..c7ec0b204 100644 --- a/lib/src/phy/phch/pmch.c +++ b/lib/src/phy/phch/pmch.c @@ -378,7 +378,7 @@ int srslte_pmch_decode_multi(srslte_pmch_t *q, } // No tx diversity in MBSFN - srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, q->nof_rx_antennas, cfg->nbits[0].nof_re, 1.0f, noise_estimate); + srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, NULL, q->nof_rx_antennas, cfg->nbits[0].nof_re, 1.0f, noise_estimate); if (SRSLTE_VERBOSE_ISDEBUG()) { DEBUG("SAVED FILE subframe.dat: received subframe symbols\n"); diff --git a/lib/src/phy/phch/pucch.c b/lib/src/phy/phch/pucch.c index b1317de3e..dd3977757 100644 --- a/lib/src/phy/phch/pucch.c +++ b/lib/src/phy/phch/pucch.c @@ -787,7 +787,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, } // Equalization - srslte_predecoding_single(q->z_tmp, q->ce, q->z, nof_re, 1.0f, noise_estimate); + srslte_predecoding_single(q->z_tmp, q->ce, q->z, NULL, nof_re, 1.0f, noise_estimate); // Perform ML-decoding float corr=0, corr_max=-1e9; diff --git a/lib/src/phy/phch/pusch.c b/lib/src/phy/phch/pusch.c index feb4e8b4f..aa049f7c0 100644 --- a/lib/src/phy/phch/pusch.c +++ b/lib/src/phy/phch/pusch.c @@ -596,7 +596,7 @@ int srslte_pusch_decode(srslte_pusch_t *q, } // Equalization - srslte_predecoding_single(q->d, q->ce, q->z, cfg->nbits.nof_re, 1.0f, noise_estimate); + srslte_predecoding_single(q->d, q->ce, q->z, NULL, cfg->nbits.nof_re, 1.0f, noise_estimate); // DFT predecoding srslte_dft_precoding(&q->dft_precoding, q->z, q->d, cfg->grant.L_prb, cfg->nbits.nof_symb); From 8cabfa82cf80a40d5c0de822f5ab59abc69e0e6c Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 28 Feb 2018 12:30:34 +0100 Subject: [PATCH 02/70] Added CSI report enable option in SRS UE --- lib/include/srslte/interfaces/ue_interfaces.h | 1 + srsue/src/main.cc | 3 +++ srsue/src/phy/phch_worker.cc | 1 + srsue/ue.conf.example | 4 ++++ 4 files changed, 9 insertions(+) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index f18a6737b..735e1d02d 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -493,6 +493,7 @@ typedef struct { bool rssi_sensor_enabled; bool sic_pss_enabled; float rx_gain_offset; + bool pdsch_csi_enabled; } phy_args_t; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 1cac2092d..cce7568b1 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -269,6 +269,9 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.estimator_fil_w)->default_value(0.1), "Chooses the coefficients for the 3-tap channel estimator centered filter.") + ("expert.pdsch_csi_enabled", + bpo::value(&args->expert.phy.pdsch_csi_enabled)->default_value(false), + "Stores the Channel State Information and uses it for weightening the softbits. It is only compatible with TM1.") ("rf_calibration.tx_corr_dc_gain", bpo::value(&args->rf_cal.tx_corr_dc_gain)->default_value(0.0), "TX DC offset gain correction") diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 6a533759b..ce4fb5d7f 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -137,6 +137,7 @@ bool phch_worker::init(uint32_t max_prb, srslte::log *log_h, srslte::log *log_ph srslte_chest_dl_cfo_estimate_enable(&ue_dl.chest, phy->args->cfo_ref_mask!=0, phy->args->cfo_ref_mask); srslte_ue_ul_set_normalization(&ue_ul, true); srslte_ue_ul_set_cfo_enable(&ue_ul, true); + srslte_pdsch_enable_csi(&ue_dl.pdsch, phy->args->pdsch_csi_enabled); mem_initiated = true; diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index b8cc43c2e..a288470d3 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -173,6 +173,9 @@ enable = false # cfo_loop_pss_timeout: After the PSS estimation is below cfo_loop_pss_tol for cfo_loop_pss_timeout times consecutively, # RS adjustments are allowed. # +# pdsch_csi_enabled: Stores the Channel State Information and uses it for weightening the softbits. It is only +# compatible with TM1. It is False by default. +# ##################################################################### [expert] #ip_netmask = 255.255.255.0 @@ -196,6 +199,7 @@ enable = false #pregenerate_signals = false #metrics_csv_enable = false #metrics_csv_filename = /tmp/ue_metrics.csv +#pdsch_csi_enabled = true # Caution! Only TM1 supported! # CFO related values #cfo_integer_enabled = false From 2a69211f32a032918766d28a9fbdd624c11f1d2e Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 1 Mar 2018 13:59:01 +0100 Subject: [PATCH 03/70] SCH does not terminate all codeblocks if one fail. Also, SCH does not decode blocks with CRC=OK --- lib/include/srslte/phy/fec/softbuffer.h | 3 ++ lib/src/phy/fec/softbuffer.c | 46 ++++++++++++++++++++++--- lib/src/phy/phch/sch.c | 31 +++++++++++++---- 3 files changed, 69 insertions(+), 11 deletions(-) diff --git a/lib/include/srslte/phy/fec/softbuffer.h b/lib/include/srslte/phy/fec/softbuffer.h index a47cc7b96..3949134d8 100644 --- a/lib/include/srslte/phy/fec/softbuffer.h +++ b/lib/include/srslte/phy/fec/softbuffer.h @@ -42,6 +42,9 @@ typedef struct SRSLTE_API { uint32_t max_cb; int16_t **buffer_f; + uint8_t **data; + bool *cb_crc; + bool tb_crc; } srslte_softbuffer_rx_t; typedef struct SRSLTE_API { diff --git a/lib/src/phy/fec/softbuffer.c b/lib/src/phy/fec/softbuffer.c index 8efa937cb..9ed526825 100644 --- a/lib/src/phy/fec/softbuffer.c +++ b/lib/src/phy/fec/softbuffer.c @@ -47,32 +47,56 @@ int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, uint32_t nof_prb) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { - ret = SRSLTE_ERROR; - bzero(q, sizeof(srslte_softbuffer_rx_t)); ret = srslte_ra_tbs_from_idx(26, nof_prb); if (ret != SRSLTE_ERROR) { q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; + ret = SRSLTE_ERROR; q->buffer_f = srslte_vec_malloc(sizeof(int16_t*) * q->max_cb); if (!q->buffer_f) { perror("malloc"); - return SRSLTE_ERROR; + goto clean_exit; } + q->data = srslte_vec_malloc(sizeof(uint8_t*) * q->max_cb); + if (!q->data) { + perror("malloc"); + goto clean_exit; + } + + q->cb_crc = srslte_vec_malloc(sizeof(bool) * q->max_cb); + if (!q->cb_crc) { + perror("malloc"); + goto clean_exit; + } + bzero(q->cb_crc, sizeof(bool) * q->max_cb); + // FIXME: Use HARQ buffer limitation based on UE category for (uint32_t i=0;imax_cb;i++) { q->buffer_f[i] = srslte_vec_malloc(sizeof(int16_t) * SOFTBUFFER_SIZE); if (!q->buffer_f[i]) { perror("malloc"); - return SRSLTE_ERROR; + goto clean_exit; + } + + q->data[i] = srslte_vec_malloc(sizeof(uint8_t) * 6144/8); + if (!q->data[i]) { + perror("malloc"); + goto clean_exit; } } //srslte_softbuffer_rx_reset(q); ret = SRSLTE_SUCCESS; } } + + clean_exit: + if (ret != SRSLTE_SUCCESS) { + srslte_softbuffer_rx_free(q); + } + return ret; } @@ -86,6 +110,17 @@ void srslte_softbuffer_rx_free(srslte_softbuffer_rx_t *q) { } free(q->buffer_f); } + if (q->data) { + for (uint32_t i=0;imax_cb;i++) { + if (q->data[i]) { + free(q->data[i]); + } + } + free(q->data); + } + if (q->cb_crc) { + free(q->cb_crc); + } bzero(q, sizeof(srslte_softbuffer_rx_t)); } } @@ -110,6 +145,9 @@ void srslte_softbuffer_rx_reset_cb(srslte_softbuffer_rx_t *q, uint32_t nof_cb) { } } } + if (q->cb_crc) { + bzero(q->cb_crc, sizeof(bool) * q->max_cb); + } } diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index e6b7d49b9..b679e00f9 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -336,14 +336,17 @@ bool decode_tb_cb(srslte_sch_t *q, decoder_input[i] = NULL; } + uint32_t remaining_cb = 0; for (int i=0;icb_crc[i]; + if (softbuffer->cb_crc[i] == false) { + remaining_cb ++; + } } srslte_tdec_reset(&q->decoder, cb_len); - uint32_t remaining_cb = nof_cb; - q->nof_iterations = 0; while(remaining_cb>0) { @@ -401,7 +404,8 @@ bool decode_tb_cb(srslte_sch_t *q, // CRC is OK if (!srslte_crc_checksum_byte(crc_ptr, q->cb_in, len_crc)) { - memcpy(&data[(cb_idx[i]*rlen)/8], q->cb_in, rlen/8 * sizeof(uint8_t)); + memcpy(softbuffer->data[cb_idx[i]], q->cb_in, rlen/8 * sizeof(uint8_t)); + softbuffer->cb_crc[cb_idx[i]] = true; q->nof_iterations += srslte_tdec_get_nof_iterations_cb(&q->decoder, i); @@ -418,15 +422,28 @@ bool decode_tb_cb(srslte_sch_t *q, cb_idx[i], remaining_cb, i, first_cb, nof_cb); q->nof_iterations += q->max_iterations; - q->nof_iterations /= (nof_cb-remaining_cb+1); - return false; + srslte_tdec_reset_cb(&q->decoder, i); + remaining_cb--; + decoder_input[i] = NULL; + cb_idx[i] = 0; } } } } + softbuffer->tb_crc = true; + for (int i = 0; i < nof_cb && softbuffer->tb_crc; i++) { + /* If one CB failed return false */ + softbuffer->tb_crc = softbuffer->cb_crc[i]; + } + if (softbuffer->tb_crc) { + for (int i = 0; i < nof_cb; i++) { + memcpy(&data[i * rlen / 8], softbuffer->data[i], rlen/8 * sizeof(uint8_t)); + } + } + q->nof_iterations /= nof_cb; - return true; + return softbuffer->tb_crc; } /** From ec901373d4487b591c2a735677f8f251c05f2bfb Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 1 Mar 2018 13:58:04 +0100 Subject: [PATCH 04/70] Correction ofo simd.h for AVX512 --- lib/include/srslte/phy/utils/simd.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/include/srslte/phy/utils/simd.h b/lib/include/srslte/phy/utils/simd.h index 3b5a00a8a..3223c18a7 100644 --- a/lib/include/srslte/phy/utils/simd.h +++ b/lib/include/srslte/phy/utils/simd.h @@ -707,11 +707,13 @@ static inline void srslte_simd_cf_storeu(float *re, float *im, simd_cf_t simdreg static inline simd_f_t srslte_simd_cf_re(simd_cf_t in) { simd_f_t out = in.re; +#ifndef LV_HAVE_AVX512 #ifdef LV_HAVE_AVX2 /* Permute for AVX registers (mis SSE registers) */ const __m256i idx = _mm256_setr_epi32(0, 2, 4, 6, 1, 3, 5, 7); out = _mm256_permutevar8x32_ps(out, idx); #endif /* LV_HAVE_AVX2 */ +#endif /* LV_HAVE_AVX512 */ return out; } From 5a8454f5a8a0511cd3726f0e8b0eac8b86bed1d0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 13:44:19 +0100 Subject: [PATCH 05/70] Fix for staying on PLMN search after disconnect --- srsue/src/phy/phch_worker.cc | 2 +- srsue/src/upper/rrc.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 88c9b54c8..4546788ec 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -529,7 +529,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) if (srslte_ue_dl_find_dl_dci_type(&ue_dl, phy->config->dedicated.antenna_info_explicit_value.tx_mode, cfi, tti%10, dl_rnti, type, &dci_msg) != 1) { if (type == SRSLTE_RNTI_RAR) { - Info("RAR not found\n"); + Info("RAR not found, SNR=%.1f dB\n", 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))); } return false; } diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 7c2798658..37ae14e8c 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -767,9 +767,9 @@ void rrc::earfcn_end() { rrc_log->info("Finished searching cells in EARFCN set while in state %s\n", rrc_state_text[state]); // If searching for PLMN, indicate NAS we scanned all frequencies - if (state == RRC_STATE_PLMN_SELECTION) { + if (state >= RRC_STATE_PLMN_SELECTION && state < RRC_STATE_CONNECTING) { nas->plmn_search_end(); - } else if (state == RRC_STATE_CONNECTED) { + } else if (state >= RRC_STATE_CONNECTING && state < RRC_STATE_LEAVE_CONNECTED) { leave_connected(); } } From add125a01f4884d279f291b899595f9665b8990b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 12:26:49 +0100 Subject: [PATCH 06/70] check expiration of poll_retx_timer and schedule retx if needed --- lib/src/upper/rlc_am.cc | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index f4dced1ec..e6e1ff279 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -198,7 +198,7 @@ uint32_t rlc_am::get_bearer() void rlc_am::write_sdu(byte_buffer_t *sdu) { tx_sdu_queue.write(sdu); - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size()); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_queue_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size()); } /**************************************************************************** @@ -273,6 +273,27 @@ uint32_t rlc_am::get_buffer_state() goto unlock_and_return; } + // check if pollRetx timer expired (Section 5.2.2.3 in TS 36.322) + if (poll_retx()) { + // if both tx and retx buffer are empty, retransmit next PDU to be ack'ed + log->info("Poll reTx timer expired (lcid=%d)\n", lcid); + if ((tx_window.size() > 0 && retx_queue.size() == 0 && tx_sdu_queue.size() == 0)) { + std::map::iterator it = tx_window.find(vt_s - 1); + if (it != tx_window.end()) { + log->info("Schedule last PDU (SN=%d) for reTx.\n", vt_s - 1); + rlc_amd_retx_t retx; + retx.is_segment = false; + retx.so_start = 0; + retx.so_end = tx_window[vt_s - 1].buf->N_bytes; + retx.sn = vt_s - 1; + retx_queue.push_back(retx); + } else { + log->error("Found invalid PDU in tx_window.\n"); + } + poll_retx_timeout.start(cfg.t_poll_retx); + } + } + // Bytes needed for retx if(retx_queue.size() > 0) { rlc_amd_retx_t retx = retx_queue.front(); From 853f7746074ac5e4d33edd9f281c6706a36028c8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 13:59:29 +0100 Subject: [PATCH 07/70] add threaded timeout test --- lib/include/srslte/common/timeout.h | 9 ++++- lib/test/common/timeout_test.cc | 61 ++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/lib/include/srslte/common/timeout.h b/lib/include/srslte/common/timeout.h index 2c9560729..4174b0237 100644 --- a/lib/include/srslte/common/timeout.h +++ b/lib/include/srslte/common/timeout.h @@ -84,7 +84,6 @@ public: } void thread_func() { - // substract time elapsed until now from timer duration gettimeofday(&start_time[2], NULL); get_time_interval(start_time); @@ -105,6 +104,14 @@ public: return false; } } + int32_t get_msec_to_expire() { + if (running) { + gettimeofday(&start_time[2], NULL); + get_time_interval(start_time); + return (duration_msec*1000 - start_time[0].tv_usec)/1000; + } + return 0; + } bool is_running() { return running; diff --git a/lib/test/common/timeout_test.cc b/lib/test/common/timeout_test.cc index 5c08e1b66..c2451cdb0 100644 --- a/lib/test/common/timeout_test.cc +++ b/lib/test/common/timeout_test.cc @@ -64,7 +64,43 @@ private: pthread_mutex_t mutex; }; -int main(int argc, char **argv) { + +int timer_thread_test() +{ + bool result; + uint32_t id = 0; + uint32_t duration_msec = 5; + uint32_t result_tolerance = 1; + + callback c; + timeout t; + + gettimeofday(&c.start_time[1], NULL); + t.start(duration_msec); + + while (t.is_running() && !t.expired()) { + printf("time to expire=%dms\n", t.get_msec_to_expire()); + usleep(1000); + } + + gettimeofday(&c.start_time[2], NULL); + get_time_interval(c.start_time); + uint32_t diff_ms = c.start_time[0].tv_usec*1e-3; + printf("Target duration: %dms, started: %ld:%ld, ended: %ld:%ld, actual duration %dms\n", + duration_msec, c.start_time[1].tv_sec, c.start_time[1].tv_usec, c.start_time[2].tv_sec, c.start_time[2].tv_usec, diff_ms); + + result = (duration_msec - result_tolerance <= diff_ms < duration_msec + result_tolerance); + + if(result) { + printf("Timer thread test passed\n"); + return 0; + }else{ + return -1; + } +} + +int single_thread_test() +{ bool result; uint32_t id = 0; uint32_t duration_msec = 5; @@ -84,10 +120,25 @@ int main(int argc, char **argv) { result = (diff_ms == duration_msec); if(result) { - printf("Passed\n"); - exit(0); + printf("Single thread test passed\n"); + return 0; }else{ - printf("Failed\n;"); - exit(1); + return -1; } } + + +int main(int argc, char **argv) +{ + if (single_thread_test()) { + printf("Single thread test failed.\n"); + return -1; + } + + if (timer_thread_test()) { + printf("Timer thread test failed.\n"); + return -1; + } + + return 0; +} From d84f6d3d41b08a634536ee46a1c907b0ee7104c9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 13:59:57 +0100 Subject: [PATCH 08/70] add parameter to change loglevel in rlc am stresser --- lib/test/upper/rlc_am_stress_test.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index bdee2248b..fb83e4cfd 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -46,6 +46,7 @@ typedef struct { uint32_t sdu_gen_delay_usec; uint32_t pdu_tx_delay_usec; bool reestablish; + uint32_t log_level; } stress_test_args_t; void parse_args(stress_test_args_t *args, int argc, char *argv[]) { @@ -64,7 +65,8 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) { ("sdu_gen_delay", bpo::value(&args->sdu_gen_delay_usec)->default_value(10), "SDU generation delay (usec)") ("pdu_tx_delay", bpo::value(&args->pdu_tx_delay_usec)->default_value(10), "Delay in MAC for transfering PDU from tx'ing RLC to rx'ing RLC (usec)") ("error_rate", bpo::value(&args->error_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped") - ("reestablish", bpo::value(&args->reestablish)->default_value(false), "Mimic RLC reestablish during execution"); + ("reestablish", bpo::value(&args->reestablish)->default_value(false), "Mimic RLC reestablish during execution") + ("loglevel", bpo::value(&args->log_level)->default_value(srslte::LOG_LEVEL_DEBUG), "Log level (1=Error,2=Warning,3=Info,4=Debug"); // these options are allowed on the command line bpo::options_description cmdline_options; @@ -81,6 +83,11 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) { cout << common << endl << general << endl; exit(0); } + + if (args->log_level > 4) { + args->log_level = 4; + printf("Set log level to %d (%s)\n", args->log_level, srslte::log_level_text[args->log_level]); + } } class mac_reader @@ -260,8 +267,8 @@ void stress_test(stress_test_args_t args) { srslte::log_filter log1("RLC_AM_1"); srslte::log_filter log2("RLC_AM_2"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log2.set_level(srslte::LOG_LEVEL_DEBUG); + log1.set_level((LOG_LEVEL_ENUM)args.log_level); + log2.set_level((LOG_LEVEL_ENUM)args.log_level); log1.set_hex_limit(-1); log2.set_hex_limit(-1); From 77c8bf08cf5608fee21690ed0162b1d5857c982e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 14:00:29 +0100 Subject: [PATCH 09/70] remove newlines --- lib/src/common/buffer_pool.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/src/common/buffer_pool.cc b/lib/src/common/buffer_pool.cc index e41668abf..3bb191143 100644 --- a/lib/src/common/buffer_pool.cc +++ b/lib/src/common/buffer_pool.cc @@ -54,12 +54,5 @@ void byte_buffer_pool::cleanup(void) } pthread_mutex_unlock(&instance_mutex); } - - - - - - - } // namespace srsue From f5e3049f6376cca927b71542a8edc0487bb9fc36 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 14:46:50 +0100 Subject: [PATCH 10/70] add check for possible buffer pool misallocation in RRC/NAS/GW --- srsue/src/upper/gw.cc | 8 ++++++-- srsue/src/upper/nas.cc | 13 +++++++++++++ srsue/src/upper/rrc.cc | 11 ++++++++--- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/srsue/src/upper/gw.cc b/srsue/src/upper/gw.cc index 65748f57b..fbf4bca9f 100644 --- a/srsue/src/upper/gw.cc +++ b/srsue/src/upper/gw.cc @@ -242,7 +242,11 @@ void gw::run_thread() struct iphdr *ip_pkt; uint32 idx = 0; int32 N_bytes; - srslte::byte_buffer_t *pdu = pool_allocate; + srslte::byte_buffer_t *pdu = pool_allocate; + if (!pdu) { + gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n"); + return; + } const static uint32_t ATTACH_TIMEOUT_MS = 10000; const static uint32_t ATTACH_MAX_ATTEMPTS = 3; @@ -307,7 +311,7 @@ void gw::run_thread() do { pdu = pool_allocate; if (!pdu) { - printf("Not enough buffers in pool\n"); + gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n"); usleep(100000); } } while(!pdu); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 0a5b597e4..5d766776a 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -812,6 +812,11 @@ void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { void nas::send_attach_request() { LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; byte_buffer_t *msg = pool_allocate; + if (!msg) { + nas_log->error("Fatal Error: Couldn't allocate PDU in send_attach_request().\n"); + return; + } + u_int32_t i; attach_req.eps_attach_type = LIBLTE_MME_EPS_ATTACH_TYPE_EPS_ATTACH; @@ -913,6 +918,10 @@ void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) { void nas::send_security_mode_reject(uint8_t cause) { byte_buffer_t *msg = pool_allocate; + if (!msg) { + nas_log->error("Fatal Error: Couldn't allocate PDU in send_security_mode_reject().\n"); + return; + } LIBLTE_MME_SECURITY_MODE_REJECT_MSG_STRUCT sec_mode_rej; sec_mode_rej.emm_cause = cause; @@ -928,6 +937,10 @@ void nas::send_identity_response() {} void nas::send_service_request() { byte_buffer_t *msg = pool_allocate; + if (!msg) { + nas_log->error("Fatal Error: Couldn't allocate PDU in send_service_request().\n"); + return; + } // Pack the service request message directly msg->msg[0] = (LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 37ae14e8c..56d0eb6ce 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1265,9 +1265,14 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGU byte_buffer_t *nas_sdu; for (i = 0; i < reconfig->N_ded_info_nas; i++) { nas_sdu = pool_allocate; - memcpy(nas_sdu->msg, &reconfig->ded_info_nas_list[i].msg, reconfig->ded_info_nas_list[i].N_bytes); - nas_sdu->N_bytes = reconfig->ded_info_nas_list[i].N_bytes; - nas->write_pdu(lcid, nas_sdu); + if (nas_sdu) { + memcpy(nas_sdu->msg, &reconfig->ded_info_nas_list[i].msg, reconfig->ded_info_nas_list[i].N_bytes); + nas_sdu->N_bytes = reconfig->ded_info_nas_list[i].N_bytes; + nas->write_pdu(lcid, nas_sdu); + } else { + rrc_log->error("Fatal Error: Couldn't allocate PDU in handle_rrc_con_reconfig().\n"); + return; + } } } } From 4575a9e610291846176e3e98a3ca69881738a810 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 15:20:23 +0100 Subject: [PATCH 11/70] add further checks for pool allocate return in srsENB and RLC UM/TM --- lib/src/upper/rlc_tm.cc | 12 ++++++++---- lib/src/upper/rlc_um.cc | 23 ++++++++++++++++++++++- srsenb/src/upper/gtpu.cc | 4 ++++ srsenb/src/upper/s1ap.cc | 32 ++++++++++++++++++++++++++++---- 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index bcf3cd20a..b9d41d3f2 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -125,10 +125,14 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes) void rlc_tm::write_pdu(uint8_t *payload, uint32_t nof_bytes) { byte_buffer_t *buf = pool_allocate; - memcpy(buf->msg, payload, nof_bytes); - buf->N_bytes = nof_bytes; - buf->set_timestamp(); - pdcp->write_pdu(lcid, buf); + if (buf) { + memcpy(buf->msg, payload, nof_bytes); + buf->N_bytes = nof_bytes; + buf->set_timestamp(); + pdcp->write_pdu(lcid, buf); + } else { + log->error("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu().\n"); + } } } // namespace srsue diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index a365a4501..647494552 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -448,8 +448,13 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) void rlc_um::reassemble_rx_sdus() { - if(!rx_sdu) + if(!rx_sdu) { rx_sdu = pool_allocate; + if (!rx_sdu) { + log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + return; + } + } // First catch up with lower edge of reordering window while(!inside_reordering_window(vr_ur)) @@ -474,6 +479,10 @@ void rlc_um::reassemble_rx_sdus() rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; + if (!rx_sdu) { + log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + return; + } } pdu_lost = false; } @@ -494,6 +503,10 @@ void rlc_um::reassemble_rx_sdus() rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; + if (!rx_sdu) { + log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + return; + } } pdu_lost = false; } @@ -528,6 +541,10 @@ void rlc_um::reassemble_rx_sdus() rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; + if (!rx_sdu) { + log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + return; + } } pdu_lost = false; } @@ -557,6 +574,10 @@ void rlc_um::reassemble_rx_sdus() rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; + if (!rx_sdu) { + log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + return; + } } pdu_lost = false; } diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index 53b7cffdb..2336f9047 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -195,6 +195,10 @@ void gtpu::rem_user(uint16_t rnti) void gtpu::run_thread() { byte_buffer_t *pdu = pool_allocate; + if (!pdu) { + gtpu_log->error("Fatal Error: Couldn't allocate buffer in gtpu::run_thread().\n"); + return; + } run_enable = true; running=true; diff --git a/srsenb/src/upper/s1ap.cc b/srsenb/src/upper/s1ap.cc index 44a564d09..a3d937a57 100644 --- a/srsenb/src/upper/s1ap.cc +++ b/srsenb/src/upper/s1ap.cc @@ -88,6 +88,10 @@ void s1ap::get_metrics(s1ap_metrics_t &m) void s1ap::run_thread() { srslte::byte_buffer_t *pdu = pool_allocate; + if (!pdu) { + s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n"); + return; + } uint32_t sz = SRSLTE_MAX_BUFFER_SIZE_BYTES - SRSLTE_BUFFER_HEADER_OFFSET; running = true; @@ -514,10 +518,15 @@ bool s1ap::handle_dlnastransport(LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT } srslte::byte_buffer_t *pdu = pool_allocate; - memcpy(pdu->msg, msg->NAS_PDU.buffer, msg->NAS_PDU.n_octets); - pdu->N_bytes = msg->NAS_PDU.n_octets; - rrc->write_dl_info(rnti, pdu); - return true; + if (pdu) { + memcpy(pdu->msg, msg->NAS_PDU.buffer, msg->NAS_PDU.n_octets); + pdu->N_bytes = msg->NAS_PDU.n_octets; + rrc->write_dl_info(rnti, pdu); + return true; + } else { + s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n"); + return false; + } } bool s1ap::handle_initialctxtsetuprequest(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg) @@ -850,6 +859,11 @@ bool s1ap::send_initial_ctxt_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_I return false; } srslte::byte_buffer_t *buf = pool_allocate; + if (!buf) { + s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_response().\n"); + return false; + } + LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu; tx_pdu.ext = false; @@ -896,6 +910,11 @@ bool s1ap::send_erab_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETU return false; } srslte::byte_buffer_t *buf = pool_allocate; + if (!buf) { + s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_erab_setup_response().\n"); + return false; + } + LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu; tx_pdu.ext = false; @@ -942,6 +961,11 @@ bool s1ap::send_initial_ctxt_setup_failure(uint16_t rnti) return false; } srslte::byte_buffer_t *buf = pool_allocate; + if (!buf) { + s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_failure().\n"); + return false; + } + LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu; tx_pdu.ext = false; tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME; From cd0373c533e3e174ab7e253a8addef18aeb29dbc Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 6 Mar 2018 15:19:47 +0000 Subject: [PATCH 12/70] opt assignment was being erased by bzero call --- lib/src/phy/rf/rf_uhd_imp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 0370fa700..b4b0cfcd6 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -80,8 +80,8 @@ static void log_overflow(rf_uhd_handler_t *h) { static void log_late(rf_uhd_handler_t *h, bool is_rx) { if (h->uhd_error_handler) { srslte_rf_error_t error; - error.opt = is_rx?1:0; bzero(&error, sizeof(srslte_rf_error_t)); + error.opt = is_rx?1:0; error.type = SRSLTE_RF_ERROR_LATE; h->uhd_error_handler(error); } From 962164277ad90b4c2f70dfab3b0571d6c8311926 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 6 Mar 2018 17:09:59 +0100 Subject: [PATCH 13/70] Normalize CSI to maximum. --- lib/src/phy/phch/pdsch.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 4cfa5c75c..c59956a71 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -659,8 +659,13 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c int16_t *e = q->e[codeword_idx]; if (q->csi_enabled) { + const uint32_t csi_max_idx = srslte_vec_max_fi(q->csi[codeword_idx], nbits->nof_bits / qm); + float csi_max = 1.0f; + if (csi_max_idx < nbits->nof_bits / qm) { + csi_max = q->csi[codeword_idx][csi_max_idx]; + } for (int i = 0; i < nbits->nof_bits / qm; i++) { - float csi = q->csi[codeword_idx][i]; + const float csi = q->csi[codeword_idx][i] / csi_max; for (int k = 0; k < qm; k++) { e[qm * i + k] = (int16_t) ((float) e[qm * i + k] * csi); } From b5421301af6acd7358ec050e4334e69b9a0083fc Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 18:45:31 +0100 Subject: [PATCH 14/70] fix mem leak in NAS test --- srsue/test/upper/nas_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 4f4ffb687..bf249f792 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -76,6 +76,7 @@ public: printf("NAS generated SDU (len=%d):\n", sdu->N_bytes); last_sdu_len = sdu->N_bytes; srslte_vec_fprint_byte(stdout, sdu->msg, sdu->N_bytes); + byte_buffer_pool::get_instance()->deallocate(sdu); } std::string get_rb_name(uint32_t lcid) { return std::string("lcid"); } uint32_t get_last_sdu_len() { return last_sdu_len; } From c3088e1d16b6a78a9bdfc95135ec3dd905da21bc Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 20:50:25 +0100 Subject: [PATCH 15/70] add cmake option to enable address sanitizer --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d67985c49..10952a010 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,7 @@ option(ENABLE_BLADERF "Enable BladeRF" ON) option(BUILD_STATIC "Attempt to statically link external deps" OFF) option(RPATH "Enable RPATH" OFF) +option(ENABLE_ASAN "Enable gcc address sanitizer" OFF) option(USE_LTE_RATES "Use standard LTE sampling rates" OFF) @@ -303,6 +304,10 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") if(NOT WIN32) ADD_CXX_COMPILER_FLAG_IF_AVAILABLE(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN) endif(NOT WIN32) + if (ENABLE_ASAN) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + endif (ENABLE_ASAN) endif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") From e933f05933abed155d95670854d2f014c3f2bed6 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 21:34:36 +0100 Subject: [PATCH 16/70] fix memleak in vector test../lib/src/phy/utils/test/vector_test.c --- lib/src/phy/utils/test/vector_test.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/phy/utils/test/vector_test.c b/lib/src/phy/utils/test/vector_test.c index 55ff2944e..623fdb526 100644 --- a/lib/src/phy/utils/test/vector_test.c +++ b/lib/src/phy/utils/test/vector_test.c @@ -265,6 +265,7 @@ TEST(srslte_vec_sum_fff, free(x); free(y); + free(z); ) TEST(srslte_vec_sub_fff, @@ -287,6 +288,7 @@ TEST(srslte_vec_sub_fff, free(x); free(y); + free(z); ) TEST(srslte_vec_dot_prod_ccc, @@ -354,6 +356,7 @@ TEST(srslte_vec_prod_ccc, } free(x); + free(y); free(z); ) @@ -407,6 +410,7 @@ TEST(srslte_vec_prod_conj_ccc, } free(x); + free(y); free(z); ) From cae09a8d5832d8a2d802d155281caa856bf08f1b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 21:35:15 +0100 Subject: [PATCH 17/70] fix mem leak in PMCH --- lib/src/phy/phch/pmch.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/src/phy/phch/pmch.c b/lib/src/phy/phch/pmch.c index c1c322f34..ed6bbf2b5 100644 --- a/lib/src/phy/phch/pmch.c +++ b/lib/src/phy/phch/pmch.c @@ -152,9 +152,8 @@ int srslte_pmch_init(srslte_pmch_t *q, uint32_t max_prb) int srslte_pmch_init_multi(srslte_pmch_t *q, uint32_t max_prb, uint32_t nof_rx_antennas) { int ret = SRSLTE_ERROR_INVALID_INPUTS; - int i; - if (q != NULL && + if (q != NULL && nof_rx_antennas <= SRSLTE_MAX_PORTS) { @@ -169,7 +168,7 @@ int srslte_pmch_init_multi(srslte_pmch_t *q, uint32_t max_prb, uint32_t nof_rx_a INFO("Init PMCH: %d PRBs, max_symbols: %d\n", max_prb, q->max_re); - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { goto clean; } @@ -189,7 +188,7 @@ int srslte_pmch_init_multi(srslte_pmch_t *q, uint32_t max_prb, uint32_t nof_rx_a goto clean; } - for (i = 0; i < SRSLTE_MAX_PORTS; i++) { + for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { q->x[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->x[i]) { goto clean; @@ -232,7 +231,7 @@ void srslte_pmch_free(srslte_pmch_t *q) { if (q->d) { free(q->d); } - for (i = 0; i < q->cell.nof_ports; i++) { + for (i = 0; i < SRSLTE_MAX_PORTS; i++) { if (q->x[i]) { free(q->x[i]); } From 4c76e98f9e049dcafe73951fd45549f60950f445 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 21:35:55 +0100 Subject: [PATCH 18/70] fix memleak in DL chest object --- lib/src/phy/ch_estimation/chest_dl.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 221bac319..ec827ec13 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -88,7 +88,7 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, uint32_t max_prb) goto clean_exit; } - q->mbsfn_refs = calloc(SRSLTE_MAX_MBSFN_AREA_IDS, sizeof(srslte_refsignal_t*)); + q->mbsfn_refs = calloc(SRSLTE_MAX_MBSFN_AREA_IDS, sizeof(srslte_refsignal_t)); if (!q->mbsfn_refs) { fprintf(stderr, "Calloc error initializing mbsfn_refs (%d)\n", ret); goto clean_exit; @@ -169,14 +169,14 @@ clean_exit: void srslte_chest_dl_free(srslte_chest_dl_t *q) { - int i; if(&q->csr_refs) srslte_refsignal_free(&q->csr_refs); if (q->mbsfn_refs) { - for (i=0; imbsfn_refs[i]) { srslte_refsignal_free(q->mbsfn_refs[i]); + free(q->mbsfn_refs[i]); } } free(q->mbsfn_refs); @@ -206,15 +206,18 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q) int srslte_chest_dl_set_mbsfn_area_id(srslte_chest_dl_t *q, uint16_t mbsfn_area_id){ - if(!q->mbsfn_refs[mbsfn_area_id]){ - q->mbsfn_refs[mbsfn_area_id] = calloc(1, sizeof(srslte_refsignal_t)); - } - if(q->mbsfn_refs[mbsfn_area_id]) { - if(srslte_refsignal_mbsfn_init(q->mbsfn_refs[mbsfn_area_id], q->cell, mbsfn_area_id)) { - return SRSLTE_ERROR; + if (mbsfn_area_id < SRSLTE_MAX_MBSFN_AREA_IDS) { + if(!q->mbsfn_refs[mbsfn_area_id]) { + q->mbsfn_refs[mbsfn_area_id] = calloc(1, sizeof(srslte_refsignal_t)); } - } - return SRSLTE_SUCCESS; + if(q->mbsfn_refs[mbsfn_area_id]) { + if(srslte_refsignal_mbsfn_init(q->mbsfn_refs[mbsfn_area_id], q->cell, mbsfn_area_id)) { + return SRSLTE_ERROR; + } + } + return SRSLTE_SUCCESS; + } + return SRSLTE_ERROR; } int srslte_chest_dl_set_cell(srslte_chest_dl_t *q, srslte_cell_t cell) From c6933f53388238491387726f082d14cec3c68f8d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 21:48:44 +0100 Subject: [PATCH 19/70] fix leak in turbocoder test --- lib/src/phy/fec/test/turbocoder_test.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/src/phy/fec/test/turbocoder_test.c b/lib/src/phy/fec/test/turbocoder_test.c index c7ca41fe3..8daeebdb8 100644 --- a/lib/src/phy/fec/test/turbocoder_test.c +++ b/lib/src/phy/fec/test/turbocoder_test.c @@ -71,8 +71,6 @@ int main(int argc, char **argv) { parse_args(argc, argv); - srslte_tcod_gentable(); - srslte_tcod_t tcod; srslte_tcod_init(&tcod, 6144); From 13efa740e846dea1b0b559d1229418d8bd1b1f39 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 22:20:38 +0100 Subject: [PATCH 20/70] Changed logic in RRC/NAS/PHY for cell/plmn search to avoid stucking in IDLE --- lib/include/srslte/interfaces/ue_interfaces.h | 4 +- srsue/hdr/phy/phch_recv.h | 2 +- srsue/hdr/upper/nas.h | 3 +- srsue/hdr/upper/rrc.h | 7 +- srsue/src/phy/phch_recv.cc | 6 +- srsue/src/phy/phch_worker.cc | 4 +- srsue/src/upper/nas.cc | 24 +- srsue/src/upper/rrc.cc | 212 ++++++++++-------- srsue/test/upper/nas_test.cc | 2 +- 9 files changed, 140 insertions(+), 124 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 923111371..b1251c0bb 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -119,7 +119,7 @@ public: virtual uint32_t get_ul_count() = 0; virtual bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) = 0; virtual bool get_k_asme(uint8_t *k_asme_, uint32_t n) = 0; - virtual void plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) = 0; + virtual bool plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) = 0; virtual void plmn_search_end() = 0; }; @@ -173,7 +173,7 @@ public: virtual uint16_t get_mnc() = 0; virtual void enable_capabilities() = 0; virtual void plmn_search() = 0; - virtual void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) = 0; + virtual void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool connect_request = false) = 0; virtual std::string get_rb_name(uint32_t lcid) = 0; }; diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 861d58229..d77e489ae 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -150,7 +150,7 @@ private: srslte_ue_mib_t ue_mib; uint32_t cnt; uint32_t timeout; - const static uint32_t SYNC_SFN_TIMEOUT = 500; + const static uint32_t SYNC_SFN_TIMEOUT = 80; }; // Class to perform cell measurements diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 6038993e0..8a1fd6ae3 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -88,9 +88,10 @@ public: uint32_t get_ul_count(); bool is_attached(); bool is_attaching(); + bool is_data_requested(); bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi); bool get_k_asme(uint8_t *k_asme_, uint32_t n); - void plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code); + bool plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code); void plmn_search_end(); // UE interface diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 55ee21097..904ae59db 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -249,7 +249,7 @@ public: void enable_capabilities(); void plmn_search(); - void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id); + void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool connect_request); // PHY interface void in_sync(); @@ -324,9 +324,6 @@ private: uint32_t plmn_select_timeout; static const uint32_t RRC_PLMN_SELECT_TIMEOUT = 10000; - uint32_t select_cell_timeout; - static const uint32_t RRC_SELECT_CELL_TIMEOUT = 1000; - uint8_t k_rrc_enc[32]; uint8_t k_rrc_int[32]; uint8_t k_up_enc[32]; @@ -401,7 +398,7 @@ private: uint16_t sysinfo_index; uint32_t last_win_start; - void select_next_cell_in_plmn(); + bool select_next_cell_in_plmn(); LIBLTE_RRC_PLMN_IDENTITY_STRUCT selected_plmn_id; bool thread_running; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index ecd2cf241..ca6a35772 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -565,8 +565,8 @@ void phch_recv::run_thread() } break; case sfn_sync::TIMEOUT: - log_h->warning("SYNC: Timeout while synchronizing SFN. Going back to cell search\n"); - phy_state = CELL_SEARCH; + log_h->warning("SYNC: Timeout while synchronizing SFN\n"); + rrc->out_of_sync(); break; case sfn_sync::IDLE: break; @@ -1271,7 +1271,7 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, for (uint32_t sf5_cnt=0;sf5_cnt max_peak && sync_res == SRSLTE_SYNC_FOUND) { diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 4546788ec..2d1b67c48 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -529,7 +529,9 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) if (srslte_ue_dl_find_dl_dci_type(&ue_dl, phy->config->dedicated.antenna_info_explicit_value.tx_mode, cfi, tti%10, dl_rnti, type, &dci_msg) != 1) { if (type == SRSLTE_RNTI_RAR) { - Info("RAR not found, SNR=%.1f dB\n", 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))); + Info("RAR not found, SNR=%.1f dB, tti=%d, cfi=%d, tx_mode=%d, cell_id=%d\n", + 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), tti, cfi, + phy->config->dedicated.antenna_info_explicit_value.tx_mode, cell.id); } return false; } diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 0a5b597e4..c25a05125 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -107,8 +107,8 @@ void nas::attach_request() { selecting_plmn = current_plmn; } } else if (state == EMM_STATE_REGISTERED) { - nas_log->info("NAS state is registered, connecting to same PLMN\n"); - rrc->plmn_select(current_plmn); + nas_log->info("NAS state is registered, selecting current PLMN\n"); + rrc->plmn_select(current_plmn, true); } else { nas_log->info("Attach request ignored. State = %s\n", emm_state_text[state]); } @@ -123,12 +123,7 @@ void nas::deattach_request() { * RRC interface ******************************************************************************/ -void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) { - - // Do not process new PLMN if already selected - if (plmn_selection == PLMN_SELECTED) { - return; - } +bool nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) { // Check if already registered for (uint32_t i=0;iinfo("Found known PLMN Id=%s\n", plmn_id_to_string(plmn_id).c_str()); if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) { nas_log->info("Connecting Home PLMN Id=%s\n", plmn_id_to_string(plmn_id).c_str()); - rrc->plmn_select(plmn_id); + rrc->plmn_select(plmn_id, state == EMM_STATE_REGISTERED_INITIATED); selecting_plmn = plmn_id; + return true; } - return; + return false; } } @@ -152,10 +148,11 @@ void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_ tracking_area_code); if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) { - rrc->plmn_select(plmn_id); + rrc->plmn_select(plmn_id, state == EMM_STATE_REGISTERED_INITIATED); selecting_plmn = plmn_id; + return true; } - + return false; } // RRC indicates that the UE has gone through all EARFCN and finished PLMN selection @@ -170,7 +167,7 @@ void nas::plmn_search_end() { plmn_id_to_string(home_plmn).c_str(), plmn_id_to_string(known_plmns[0]).c_str()); } - rrc->plmn_select(known_plmns[0]); + rrc->plmn_select(known_plmns[0], state == EMM_STATE_REGISTERED_INITIATED); } else { nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n"); if (state == EMM_STATE_REGISTERED_INITIATED && plmn_selection == PLMN_NOT_SELECTED) { @@ -538,6 +535,7 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) { state = EMM_STATE_REGISTERED; current_plmn = selecting_plmn; + plmn_selection = PLMN_SELECTED; ctxt.rx_count++; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 37ae14e8c..875785093 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -126,6 +126,8 @@ void rrc::init(phy_interface_rrc *phy_, pending_mob_reconf = false; + connection_requested = false; + // Set default values for all layers set_rrc_default(); set_phy_default(); @@ -184,10 +186,8 @@ void rrc::run_thread() { if (phy->sync_status()) { // If attempting to attach, reselect cell if (nas->is_attaching()) { - sleep(1); - rrc_log->info("RRC IDLE: NAS is attaching and camping on cell, reselecting...\n"); + rrc_log->info("RRC IDLE: NAS has pending data and camping on cell, connecting...\n"); plmn_select_rrc(selected_plmn_id); - connection_requested = true; } // If not camping on a cell } else { @@ -196,7 +196,6 @@ void rrc::run_thread() { rrc_log->info("RRC IDLE: NAS is attached, PHY not synchronized. Re-selecting cell...\n"); plmn_select_rrc(selected_plmn_id); } else if (nas->is_attaching()) { - sleep(1); rrc_log->info("RRC IDLE: NAS is attaching, searching again PLMN\n"); plmn_search(); } @@ -234,16 +233,6 @@ void rrc::run_thread() { state = RRC_STATE_CELL_SELECTED; } } - // Don't time out during reestablishment (T311 running) - if (!mac_timers->timer_get(t311)->is_running() || !phy->sync_status()) { - select_cell_timeout++; - if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) { - rrc_log->info("RRC Cell Selecting: timeout expired. Starting Cell Search...\n"); - select_cell_timeout = 0; - state = RRC_STATE_PLMN_START; - serving_cell->in_sync = false; - } - } break; case RRC_STATE_CELL_SELECTED: @@ -258,9 +247,9 @@ void rrc::run_thread() { con_restablish_cell_reselected(); state = RRC_STATE_CONNECTING; connecting_timeout = 0; - } else if (connection_requested) { - connection_requested = false; + } else if (nas->is_attaching() || connection_requested) { rrc_log->info("RRC Cell Selected: Sending connection request...\n"); + connection_requested = false; send_con_request(); state = RRC_STATE_CONNECTING; connecting_timeout = 0; @@ -442,8 +431,8 @@ void rrc::plmn_search() { /* This is the NAS interface. When NAS requests to select a PLMN we have to * connect to either register or because there is pending higher layer traffic. */ -void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { - connection_requested = true; +void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool connect_request) { + connection_requested = connect_request; plmn_select_rrc(plmn_id); } @@ -451,37 +440,41 @@ void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { * selected PLMN */ void rrc::plmn_select_rrc(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { + pthread_mutex_lock(&mutex); + // If already camping on the selected PLMN, select this cell if (state == RRC_STATE_IDLE || state == RRC_STATE_CONNECTED || state == RRC_STATE_PLMN_SELECTION) { if (phy->sync_status() && selected_plmn_id.mcc == plmn_id.mcc && selected_plmn_id.mnc == plmn_id.mnc) { - rrc_log->info("Already camping on selected PLMN, connecting...\n"); + rrc_log->info("Already camping on selected PLMN\n"); } else { selected_plmn_id = plmn_id; - if (serving_cell->plmn_equals(selected_plmn_id)) { - phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + if (serving_cell->plmn_equals(selected_plmn_id) && serving_cell->in_sync) { + rrc_log->info("PLMN Id=%s selected, Selecting serving cell earfcn=%d, pci=%d\n", + plmn_id_to_string(plmn_id).c_str(), serving_cell->get_earfcn(), serving_cell->phy_cell.id); } else { bool found = false; for (uint32_t i=0;iplmn_equals(selected_plmn_id)) { - rrc_log->info("PLMN Id=%s selected, PCI=%d\n", plmn_id_to_string(plmn_id).c_str(), neighbour_cells[i]->get_pci()); + rrc_log->info("PLMN Id=%s selected, Selecting neighbour cell PCI=%d\n", plmn_id_to_string(plmn_id).c_str(), neighbour_cells[i]->get_pci()); phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell); found = true; } } if (!found) { - rrc_log->warning("Could not find any cell for the selected PLMN\n"); - state = RRC_STATE_IDLE; + rrc_log->warning("Could not find any cell for the selected PLMN. Searching another PLMN\n"); + plmn_search(); + pthread_mutex_unlock(&mutex); return; } } } state = RRC_STATE_CELL_SELECTING; - select_cell_timeout = 0; } else { rrc_log->warning("Requested PLMN select in incorrect state %s\n", rrc_state_text[state]); } + pthread_mutex_unlock(&mutex); } void rrc::set_serving_cell(uint32_t earfcn, uint32_t pci) { @@ -494,6 +487,7 @@ void rrc::set_serving_cell(uint32_t earfcn, uint32_t pci) { } void rrc::set_serving_cell(uint32_t cell_idx) { + if (cell_idx < neighbour_cells.size()) { // Remove future serving cell from neighbours to make space for current serving cell @@ -529,29 +523,37 @@ void rrc::set_serving_cell(uint32_t cell_idx) { } } -void rrc::select_next_cell_in_plmn() { +bool rrc::select_next_cell_in_plmn() { // Neighbour cells are sorted in descending order of RSRP for (uint32_t i = 0; i < neighbour_cells.size(); i++) { - if (neighbour_cells[i]->plmn_equals(selected_plmn_id) && + if (/*TODO: CHECK that PLMN matches. Currently we don't receive SIB1 of neighbour cells + * neighbour_cells[i]->plmn_equals(selected_plmn_id) && */ neighbour_cells[i]->in_sync) // matches S criteria { - // Try to select Cell - phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell); - set_serving_cell(i); - rrc_log->info("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->get_earfcn(), - serving_cell->get_cell_id()); - rrc_log->console("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->get_earfcn(), - serving_cell->get_cell_id()); - return; + // If currently connected, verify cell selection criteria + if (!serving_cell->in_sync || + (cell_selection_eval(neighbour_cells[i]->get_rsrp()) && + neighbour_cells[i]->get_rsrp() > serving_cell->get_rsrp() + 5)) + { + // Try to select Cell + set_serving_cell(i); + rrc_log->info("Selected cell idx=%d, PCI=%d, EARFCN=%d\n", + i, serving_cell->phy_cell.id, serving_cell->get_earfcn()); + rrc_log->console("Selected cell PCI=%d, EARFCN=%d\n", + serving_cell->phy_cell.id, serving_cell->get_earfcn()); + phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + state = RRC_STATE_CELL_SELECTING; + return true; + } } } - rrc_log->info("No more known cells. Starting again\n"); + return false; } void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int pci_i) { + pthread_mutex_lock(&mutex); + if (earfcn_i < 0 || pci_i < 0) { earfcn_i = serving_cell->get_earfcn(); pci_i = serving_cell->phy_cell.id; @@ -582,16 +584,22 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p } } - // Verify cell selection criteria with strongest neighbour cell (always first) - if (neighbour_cells.size() > 1 && - cell_selection_eval(neighbour_cells[0]->get_rsrp()) && - neighbour_cells[0]->get_rsrp() > serving_cell->get_rsrp() + 5) - { - set_serving_cell(0); - rrc_log->info("Selecting best neighbour cell PCI=%d, rsrp=%.1f dBm\n", serving_cell->phy_cell.id, serving_cell->get_rsrp()); - state = RRC_STATE_CELL_SELECTING; - phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); - } + // Evaluate if we need to select a new cell + select_next_cell_in_plmn(); + } + pthread_mutex_unlock(&mutex); +} + +// PHY indicates that has gone through all known EARFCN +void rrc::earfcn_end() { + rrc_log->info("Finished searching cells in EARFCN set while in state %s\n", rrc_state_text[state]); + + // If searching for PLMN, indicate NAS we scanned all frequencies + if (state == RRC_STATE_PLMN_SELECTION) { + nas->plmn_search_end(); + } else { + rrc_log->info("Restarting Cell search...\n"); + phy->cell_search_start(); } } @@ -600,51 +608,53 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p * new cell as current serving cell */ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { - bool found = false; - int cell_idx = -1; - + int cell_idx = -1; + bool found = true; + + pthread_mutex_lock(&mutex); + if (serving_cell->equals(earfcn, phy_cell.id)) { serving_cell->set_rsrp(rsrp); - found = true; } else { // Check if cell is in our list of neighbour cells cell_idx = find_neighbour_cell(earfcn, phy_cell.id); if (cell_idx >= 0) { set_serving_cell(cell_idx); serving_cell->set_rsrp(rsrp); - found = true; + } else { + found = false; + if (!add_neighbour_cell(earfcn, phy_cell, rsrp)) { + rrc_log->info( + "No more space for neighbour cells (detected cell RSRP=%.1f dBm worse than current %d neighbours)\n", + rsrp, + NOF_NEIGHBOUR_CELLS); + } else { + set_serving_cell(earfcn, phy_cell.id); + serving_cell->set_rsrp(rsrp); + } } } - if (found) { - if (!serving_cell->has_sib1()) { - si_acquire_state = SI_ACQUIRE_SIB1; - } else if (state == RRC_STATE_PLMN_SELECTION) { - for (uint32_t j = 0; j < serving_cell->sib1ptr()->N_plmn_ids; j++) { - nas->plmn_found(serving_cell->sib1ptr()->plmn_id[j].id, serving_cell->sib1ptr()->tracking_area_code); - } - usleep(5000); - phy->cell_search_next(); + pthread_mutex_unlock(&mutex); + + if (!serving_cell->has_sib1()) { + si_acquire_state = SI_ACQUIRE_SIB1; + } else if (state == RRC_STATE_PLMN_SELECTION) { + bool ret = false; + for (uint32_t j = 0; j < serving_cell->sib1ptr()->N_plmn_ids; j++) { + ret |= nas->plmn_found(serving_cell->sib1ptr()->plmn_id[j].id, serving_cell->sib1ptr()->tracking_area_code); } - } else { - // add to list of known cells and set current_cell - if (!add_neighbour_cell(earfcn, phy_cell, rsrp)) { - rrc_log->info("No more space for neighbour cells (detected cell RSRP=%.1f dBm worse than current %d neighbours)\n", - rsrp, NOF_NEIGHBOUR_CELLS); - usleep(5000); + // If any of the PLMNs in this cell is selected, search next cell + if (!ret) { phy->cell_search_next(); - } else { - set_serving_cell(earfcn, phy_cell.id); - si_acquire_state = SI_ACQUIRE_SIB1; } } rrc_log->info("%s %s cell EARFCN=%d, PCI=%d, RSRP=%.1f dBm\n", found?"Updating":"Adding", - cell_idx>=0?"neighbour":"serving", - serving_cell->get_earfcn(), - serving_cell->phy_cell.id, - serving_cell->get_rsrp()); + cell_idx>=0?"neighbour":"serving", earfcn, phy_cell.id, rsrp); + + } bool sort_rsrp(cell_t *u1, cell_t *u2) { @@ -668,6 +678,8 @@ void rrc::clean_neighbours() struct timeval now; gettimeofday(&now, NULL); + pthread_mutex_lock(&mutex); + std::vector::iterator it = neighbour_cells.begin(); while(it != neighbour_cells.end()) { if ((*it)->timeout_secs(now) > NEIGHBOUR_TIMEOUT) { @@ -677,6 +689,7 @@ void rrc::clean_neighbours() ++it; } } + pthread_mutex_unlock(&mutex); } // Sort neighbour cells by decreasing order of RSRP @@ -695,13 +708,17 @@ void rrc::sort_neighbour_cells() std::sort(neighbour_cells.begin(), neighbour_cells.end(), sort_rsrp); - char ordered[512]; - int n=0; - n += snprintf(ordered, 512, "[pci=%d, rsrsp=%.2f", neighbour_cells[0]->phy_cell.id, neighbour_cells[0]->get_rsrp()); - for (uint32_t i=1;iget_pci(), neighbour_cells[i]->get_rsrp()); + if (neighbour_cells.size() > 0) { + char ordered[512]; + int n=0; + n += snprintf(ordered, 512, "[pci=%d, rsrsp=%.2f", neighbour_cells[0]->phy_cell.id, neighbour_cells[0]->get_rsrp()); + for (uint32_t i=1;iget_pci(), neighbour_cells[i]->get_rsrp()); + } + rrc_log->info("Neighbours: %s]\n", ordered); + } else { + rrc_log->info("Neighbours: Empty\n"); } - rrc_log->info("Neighbours: %s]\n", ordered); } bool rrc::add_neighbour_cell(cell_t *new_cell) { @@ -744,7 +761,7 @@ bool rrc::add_neighbour_cell(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp if (cell_idx >= 0) { neighbour_cells[cell_idx]->set_rsrp(rsrp); sort_neighbour_cells(); - return true; + return true; } // If not, create a new one @@ -762,18 +779,6 @@ int rrc::find_neighbour_cell(uint32_t earfcn, uint32_t pci) { return -1; } -// PHY indicates that has gone through all known EARFCN -void rrc::earfcn_end() { - rrc_log->info("Finished searching cells in EARFCN set while in state %s\n", rrc_state_text[state]); - - // If searching for PLMN, indicate NAS we scanned all frequencies - if (state >= RRC_STATE_PLMN_SELECTION && state < RRC_STATE_CONNECTING) { - nas->plmn_search_end(); - } else if (state >= RRC_STATE_CONNECTING && state < RRC_STATE_LEAVE_CONNECTED) { - leave_connected(); - } -} - // Cell reselection in IDLE Section 5.2.4 of 36.304 void rrc::cell_reselection_eval(float rsrp, float rsrq) { @@ -826,7 +831,6 @@ float rrc::get_squal(float Qqualmeas) { // Detection of physical layer problems in RRC_CONNECTED (5.3.11.1) void rrc::out_of_sync() { - serving_cell->in_sync = false; if (state == RRC_STATE_CONNECTED) { if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) { n310_cnt++; @@ -838,9 +842,23 @@ void rrc::out_of_sync() { n310_cnt = 0; } } - } else { - phy->sync_reset(); + } else if (state != RRC_STATE_LEAVE_CONNECTED) { + if (!mac_timers->timer_get(t311)->is_running()) { + if (serving_cell->in_sync) { + rrc_log->info("Detected out-of-sync while in IDLE. Resetting sync\n"); + phy->sync_reset(); + } else { + rrc_log->info("Detected out-of-sync while in IDLE. Selecting another cell in the PLMN\n"); + if (!select_next_cell_in_plmn()) { + rrc_log->info("Could not find any available cell in this PLMN. Searching PLMN again.\n"); + plmn_search(); + } + } + } else { + rrc_log->info("Detected out-of-sync while T311 is running\n"); + } } + serving_cell->in_sync = false; } // Recovery of physical layer problems (5.3.11.2) diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 4f4ffb687..5a4a082ba 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -81,7 +81,7 @@ public: uint32_t get_last_sdu_len() { return last_sdu_len; } void plmn_search() {}; - void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {}; + void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool con_req) {}; uint16_t get_mcc() { return mcc; } uint16_t get_mnc() { return mnc; } From ac194ae7b170d98c0a5d622cdff97d1b5c5709ed Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 22:24:07 +0100 Subject: [PATCH 21/70] fix warning in timeout test --- lib/test/common/timeout_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test/common/timeout_test.cc b/lib/test/common/timeout_test.cc index c2451cdb0..4bde95f66 100644 --- a/lib/test/common/timeout_test.cc +++ b/lib/test/common/timeout_test.cc @@ -89,7 +89,7 @@ int timer_thread_test() printf("Target duration: %dms, started: %ld:%ld, ended: %ld:%ld, actual duration %dms\n", duration_msec, c.start_time[1].tv_sec, c.start_time[1].tv_usec, c.start_time[2].tv_sec, c.start_time[2].tv_usec, diff_ms); - result = (duration_msec - result_tolerance <= diff_ms < duration_msec + result_tolerance); + result = ((duration_msec - result_tolerance) < diff_ms || diff_ms < (duration_msec + result_tolerance)); if(result) { printf("Timer thread test passed\n"); From ac0f9345582539cfe14f3cd2601c9f055135962d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 6 Mar 2018 22:33:57 +0100 Subject: [PATCH 22/70] fix leaks in viterbi and modem tests --- lib/src/phy/fec/test/viterbi_test.c | 1 + lib/src/phy/modem/test/modem_test.c | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/src/phy/fec/test/viterbi_test.c b/lib/src/phy/fec/test/viterbi_test.c index 28c60bce6..e4cf6f312 100644 --- a/lib/src/phy/fec/test/viterbi_test.c +++ b/lib/src/phy/fec/test/viterbi_test.c @@ -279,6 +279,7 @@ int main(int argc, char **argv) { free(llr); free(llr_c); free(data_rx); + free(data_rx2); if (snr_points == 1) { int expected_errors = get_expected_errors(nof_frames, seed, frame_length, tail_biting, ebno_db); diff --git a/lib/src/phy/modem/test/modem_test.c b/lib/src/phy/modem/test/modem_test.c index 600115386..ed9bef522 100644 --- a/lib/src/phy/modem/test/modem_test.c +++ b/lib/src/phy/modem/test/modem_test.c @@ -197,6 +197,7 @@ int main(int argc, char **argv) { } } + free(llr2); free(llr); free(symbols); free(symbols_bytes); From a85368cac0dd9cb50f2eb1878e4652df8ba882ae Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 7 Mar 2018 00:28:52 +0100 Subject: [PATCH 23/70] Discard duplicated TB after timeout --- srsue/hdr/mac/dl_harq.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index f4c557898..cfdfdfc5f 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -190,6 +190,9 @@ private: } private: + + const static int RESET_DUPLICATE_TIMEOUT = 8*6; + class dl_tb_process { public: dl_tb_process(void) { @@ -273,6 +276,10 @@ private: grant.last_tti = cur_grant.tti; memcpy(&cur_grant, &grant, sizeof(Tgrant)); + if (payload_buffer_ptr) { + Warning("DL PID %d: Allocating buffer already allocated\n", pid); + } + // Instruct the PHY To combine the received data and attempt to decode it if (pid == HARQ_BCCH_PID) { payload_buffer_ptr = harq_entity->demux_unit->request_buffer_bcch(cur_grant.n_bytes[tid]); @@ -294,8 +301,14 @@ private: } else { action->default_ack[tid] = true; - Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK (grant_tti=%d, ndi=%d, sz=%d)\n", - pid, cur_grant.tti, cur_grant.ndi[tid], cur_grant.n_bytes[tid]); + uint32_t interval = srslte_tti_interval(grant.tti, cur_grant.tti); + Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK (grant_tti=%d, ndi=%d, sz=%d, reset=%s)\n", + pid, cur_grant.tti, cur_grant.ndi[tid], cur_grant.n_bytes[tid], interval>RESET_DUPLICATE_TIMEOUT?"yes":"no"); + if (interval > RESET_DUPLICATE_TIMEOUT) { + pthread_mutex_unlock(&mutex); + reset(); + pthread_mutex_lock(&mutex); + } } if (pid == HARQ_BCCH_PID || harq_entity->timer_aligment_timer->is_expired()) { From c6c170e73750477eded20dd24d2704bcfe44976a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 7 Mar 2018 00:31:31 +0100 Subject: [PATCH 24/70] Do HO after correct synchronization --- srsue/hdr/upper/rrc.h | 3 +++ srsue/src/upper/rrc.cc | 28 +++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 904ae59db..8d092051a 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -311,6 +311,8 @@ private: uint16_t ho_src_rnti; cell_t ho_src_cell; + uint32_t ho_target_pci; + bool ho_syncing; phy_interface_rrc::phy_cfg_t ho_src_phy_cfg; mac_interface_rrc::mac_cfg_t ho_src_mac_cfg; bool pending_mob_reconf; @@ -542,6 +544,7 @@ private: // Helpers void ho_failed(); bool ho_prepare(); + void ho_synced(uint32_t target_pci); void rrc_connection_release(); void con_restablish_cell_reselected(); void radio_link_failure(); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 81331b2e4..935d24435 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -99,6 +99,8 @@ void rrc::init(phy_interface_rrc *phy_, state = RRC_STATE_IDLE; si_acquire_state = SI_ACQUIRE_IDLE; + ho_syncing = false; + thread_running = true; start(); @@ -611,6 +613,11 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { int cell_idx = -1; bool found = true; + if (ho_syncing && phy_cell.id == ho_target_pci) { + ho_synced(ho_target_pci); + return; + } + pthread_mutex_lock(&mutex); if (serving_cell->equals(earfcn, phy_cell.id)) { @@ -1127,7 +1134,9 @@ bool rrc::ho_prepare() { int target_cell_idx = find_neighbour_cell(serving_cell->get_earfcn(), mob_reconf.mob_ctrl_info.target_pci); if (target_cell_idx < 0) { rrc_log->console("Received HO command to unknown PCI=%d\n", mob_reconf.mob_ctrl_info.target_pci); - rrc_log->error("Could not find target cell earfcn=%d, pci=%d\n", serving_cell->get_earfcn(), mob_reconf.mob_ctrl_info.target_pci); + rrc_log->error("Could not find target cell earfcn=%d, pci=%d\n", + serving_cell->get_earfcn(), + mob_reconf.mob_ctrl_info.target_pci); return false; } @@ -1159,12 +1168,22 @@ bool rrc::ho_prepare() { mac->set_ho_rnti(mob_reconf.mob_ctrl_info.new_ue_id, mob_reconf.mob_ctrl_info.target_pci); apply_rr_config_common_dl(&mob_reconf.mob_ctrl_info.rr_cnfg_common); + ho_target_pci = neighbour_cells[target_cell_idx]->phy_cell.id; + ho_syncing = true; + rrc_log->info("Selecting new cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); if (!phy->cell_handover(neighbour_cells[target_cell_idx]->phy_cell)) { rrc_log->error("Could not synchronize with target cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); return false; } + } + return true; +} +void rrc::ho_synced(uint32_t current_pci) +{ + ho_syncing = false; + if (current_pci == ho_target_pci) { if (mob_reconf.mob_ctrl_info.rach_cnfg_ded_present) { rrc_log->info("Starting non-contention based RA with preamble_idx=%d, mask_idx=%d\n", mob_reconf.mob_ctrl_info.rach_cnfg_ded.preamble_index, @@ -1181,7 +1200,7 @@ bool rrc::ho_prepare() { ncc = mob_reconf.sec_cnfg_ho.intra_lte.next_hop_chaining_count; if (mob_reconf.sec_cnfg_ho.intra_lte.key_change_ind) { rrc_log->console("keyChangeIndicator in securityConfigHO not supported\n"); - return false; + return; } if (mob_reconf.sec_cnfg_ho.intra_lte.sec_alg_cnfg_present) { cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM) mob_reconf.sec_cnfg_ho.intra_lte.sec_alg_cnfg.cipher_alg; @@ -1198,8 +1217,11 @@ bool rrc::ho_prepare() { pdcp->config_security_all(k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); send_rrc_con_reconfig_complete(); + } else { + rrc_log->error("HO: Synchronized with incorrect cell. Target PCI=%d, current PCI=%d\n", ho_target_pci, current_pci); + ho_failed(); } - return true; + return; } void rrc::ho_ra_completed(bool ra_successful) { From bdf379ee1c24ca8c68f0fb922b1d428e4032fb71 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 7 Mar 2018 10:50:10 +0100 Subject: [PATCH 25/70] Fixed roaming PLMN attach. Add out-of-sync debugging --- srsue/src/phy/phch_recv.cc | 2 ++ srsue/src/upper/rrc.cc | 21 +++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index ca6a35772..be483b0e4 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -717,8 +717,10 @@ void phch_recv::in_sync() { // Out of sync called by worker or phch_recv every 1 or 5 ms void phch_recv::out_of_sync() { // Send RRC out-of-sync signal after 200 ms consecutive subframes + Info("Out-of-sync %d/%d\n", out_of_sync_cnt, NOF_OUT_OF_SYNC_SF); out_of_sync_cnt++; if (out_of_sync_cnt >= NOF_OUT_OF_SYNC_SF) { + Info("Sending to RRC\n"); rrc->out_of_sync(); out_of_sync_cnt = 0; in_sync_cnt = 0; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 935d24435..a08297da6 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -452,8 +452,12 @@ void rrc::plmn_select_rrc(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { selected_plmn_id = plmn_id; if (serving_cell->plmn_equals(selected_plmn_id) && serving_cell->in_sync) { - rrc_log->info("PLMN Id=%s selected, Selecting serving cell earfcn=%d, pci=%d\n", - plmn_id_to_string(plmn_id).c_str(), serving_cell->get_earfcn(), serving_cell->phy_cell.id); + rrc_log->info("PLMN Id=%s selected, Selecting serving cell earfcn=%d, pci=%d, status=%d\n", + plmn_id_to_string(plmn_id).c_str(), serving_cell->get_earfcn(), serving_cell->phy_cell.id, + phy->sync_status()); + if (!phy->sync_status()) { + phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + } } else { bool found = false; for (uint32_t i=0;iinfo("Received out-of-sync state %s. n310=%d, t311=%s, t310=%s\n", + rrc_state_text[state], n310_cnt, + mac_timers->timer_get(t311)->is_running()?"running":"stop", + mac_timers->timer_get(t310)->is_running()?"running":"stop"); if (state == RRC_STATE_CONNECTED) { if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) { n310_cnt++; @@ -1168,14 +1176,15 @@ bool rrc::ho_prepare() { mac->set_ho_rnti(mob_reconf.mob_ctrl_info.new_ue_id, mob_reconf.mob_ctrl_info.target_pci); apply_rr_config_common_dl(&mob_reconf.mob_ctrl_info.rr_cnfg_common); - ho_target_pci = neighbour_cells[target_cell_idx]->phy_cell.id; - ho_syncing = true; - rrc_log->info("Selecting new cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); if (!phy->cell_handover(neighbour_cells[target_cell_idx]->phy_cell)) { - rrc_log->error("Could not synchronize with target cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); + rrc_log->error("Could not synchronize with target cell pci=%d. Trying to return to source PCI\n", + neighbour_cells[target_cell_idx]->get_pci()); + ho_failed(); return false; } + ho_target_pci = neighbour_cells[target_cell_idx]->phy_cell.id; + ho_syncing = true; } return true; } From ac95976a6bbc9edf724efde39f4f74317d9ef16b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 7 Mar 2018 14:50:56 +0100 Subject: [PATCH 26/70] Check Cell is valid before HO. Do cell search if going back to source fails --- srsue/src/phy/phch_recv.cc | 8 +++++++- srsue/src/upper/rrc.cc | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index be483b0e4..4d4dbb78e 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -220,7 +220,7 @@ bool phch_recv::set_cell() { // Set cell in all objects if (srslte_ue_sync_set_cell(&ue_sync, cell)) { - Error("SYNC: Setting cell: initiating ue_sync"); + Error("SYNC: Setting cell: initiating ue_sync\n"); return false; } measure_p.set_cell(cell); @@ -308,6 +308,12 @@ void phch_recv::cell_search_start() { bool phch_recv::cell_handover(srslte_cell_t cell) { + + if (srslte_cell_isvalid(&cell)) { + log_h->error("Received HO command to invalid cell. ID=%d, PRB=%d, ports=%d\n", cell.id, cell.nof_prb, cell.nof_ports); + return false; + } + int cnt = 0; while(worker_com->is_any_pending_ack() && cnt < 10) { usleep(1000); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index a08297da6..fdd461ebb 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1268,7 +1268,8 @@ void rrc::ho_failed() { // Instruct PHY to resync with source PCI if (!phy->cell_handover(ho_src_cell.phy_cell)) { - rrc_log->error("Could not synchronize with target cell pci=%d\n", ho_src_cell.get_pci()); + rrc_log->error("Could not synchronize with target cell pci=%d. Going to PLMN Search\n", ho_src_cell.get_pci()); + plmn_search(); return; } From 04f6634b4908434e8cc87e4e72e4a5bbacf6abc5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Mar 2018 15:02:07 +0100 Subject: [PATCH 27/70] fix condition check in cell HO --- srsue/src/phy/phch_recv.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 4d4dbb78e..112cd03b8 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -308,8 +308,7 @@ void phch_recv::cell_search_start() { bool phch_recv::cell_handover(srslte_cell_t cell) { - - if (srslte_cell_isvalid(&cell)) { + if (!srslte_cell_isvalid(&cell)) { log_h->error("Received HO command to invalid cell. ID=%d, PRB=%d, ports=%d\n", cell.id, cell.nof_prb, cell.nof_ports); return false; } From 4af78e4960854909d82774fca42640d56158c4ba Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 7 Mar 2018 16:23:05 +0100 Subject: [PATCH 28/70] Fix invalid cell search check in previous commit --- srsue/src/phy/phch_recv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 4d4dbb78e..b7bc26a86 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -309,7 +309,7 @@ void phch_recv::cell_search_start() { bool phch_recv::cell_handover(srslte_cell_t cell) { - if (srslte_cell_isvalid(&cell)) { + if (!srslte_cell_isvalid(&cell)) { log_h->error("Received HO command to invalid cell. ID=%d, PRB=%d, ports=%d\n", cell.id, cell.nof_prb, cell.nof_ports); return false; } From 57e0c01fc4638acc41711ac94d0028c09b5dd99c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Mar 2018 15:27:08 +0100 Subject: [PATCH 29/70] check max buffer length in hex print --- lib/include/srslte/phy/utils/vector.h | 2 +- lib/src/phy/utils/vector.c | 9 ++++++++- srsue/src/mac/demux.cc | 2 +- srsue/src/phy/phch_worker.cc | 4 ++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/include/srslte/phy/utils/vector.h b/lib/include/srslte/phy/utils/vector.h index 4ec95639a..fbf000a70 100644 --- a/lib/include/srslte/phy/utils/vector.h +++ b/lib/include/srslte/phy/utils/vector.h @@ -73,7 +73,7 @@ SRSLTE_API void srslte_vec_fprint_byte(FILE *stream, uint8_t *x, const uint32_t SRSLTE_API void srslte_vec_fprint_i(FILE *stream, int *x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_s(FILE *stream, short *x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_hex(FILE *stream, uint8_t *x, const uint32_t len); -SRSLTE_API void srslte_vec_sprint_hex(char *str, uint8_t *x, const uint32_t len); +SRSLTE_API void srslte_vec_sprint_hex(char *str, const uint32_t max_str_len, uint8_t *x, const uint32_t len); /* Saves/loads a vector to a file */ SRSLTE_API void srslte_vec_save_file(char *filename, const void *buffer, const uint32_t len); diff --git a/lib/src/phy/utils/vector.c b/lib/src/phy/utils/vector.c index b97583bb8..9ccd21559 100644 --- a/lib/src/phy/utils/vector.c +++ b/lib/src/phy/utils/vector.c @@ -200,10 +200,16 @@ void srslte_vec_fprint_hex(FILE *stream, uint8_t *x, const uint32_t len) { fprintf(stream, "];\n"); } -void srslte_vec_sprint_hex(char *str, uint8_t *x, const uint32_t len) { +void srslte_vec_sprint_hex(char *str, const uint32_t max_str_len, uint8_t *x, const uint32_t len) { uint32_t i, nbytes; uint8_t byte; nbytes = len/8; + // check that hex string fits in buffer (every byte takes 3 characters, plus brackets) + if ((3*(len/8 + ((len%8)?1:0))) + 2 >= max_str_len) { + fprintf(stderr, "Buffer too small for printing hex string (max_str_len=%d, payload_len=%d).\n", max_str_len, len); + return; + } + int n=0; n+=sprintf(&str[n], "["); for (i=0;iwrite_pdu(pdu_msg->get()->get_sdu_lcid(), pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_payload_size()); } else { char tmp[1024]; - srslte_vec_sprint_hex(tmp, pdu_msg->get()->get_sdu_ptr(), 32); + srslte_vec_sprint_hex(tmp, sizeof(tmp), pdu_msg->get()->get_sdu_ptr(), 32); Error("PDU size %d exceeds maximum PDU buffer size, lcid=%d, hex=[%s]\n", pdu_msg->get()->get_payload_size(), pdu_msg->get()->get_sdu_lcid(), tmp); } diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 19106c514..8a6c5cd8b 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -577,7 +577,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) char hexstr[16]; hexstr[0]='\0'; if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { - srslte_vec_sprint_hex(hexstr, dci_msg.data, dci_msg.nof_bits); + srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); } Info("PDCCH: DL DCI %s cce_index=%2d, L=%d, n_data_bits=%d, hex=%s\n", srslte_dci_format_string(dci_msg.format), last_dl_pdcch_ncce, (1<get_level() >= srslte::LOG_LEVEL_INFO) { - srslte_vec_sprint_hex(hexstr, dci_msg.data, dci_msg.nof_bits); + srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); } // Change to last_location_ul Info("PDCCH: UL DCI Format0 cce_index=%d, L=%d, n_data_bits=%d, hex=%s\n", From 7acc021a4e4d497b43100172f9b73dc5750d63d3 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 7 Mar 2018 16:32:40 +0100 Subject: [PATCH 30/70] fix mem leak in pmch_test --- lib/src/phy/phch/test/pmch_test.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/phy/phch/test/pmch_test.c b/lib/src/phy/phch/test/pmch_test.c index a69b5d075..15634fe9b 100644 --- a/lib/src/phy/phch/test/pmch_test.c +++ b/lib/src/phy/phch/test/pmch_test.c @@ -157,6 +157,7 @@ int main(int argc, char **argv) { bzero(ce, sizeof(cf_t*)*SRSLTE_MAX_PORTS); bzero(tx_slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS); bzero(rx_slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS); + bzero(t, 3 * sizeof(struct timeval)); cell.nof_ports = 1; @@ -469,5 +470,8 @@ quit: } else { printf("Ok\n"); } + + srslte_dft_exit(); + exit(ret); } From 938e56fa2cc63eb5541b2f79b5e60e132c41a77c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 11:41:21 +0100 Subject: [PATCH 31/70] streamline log output in RLC AM/UM --- lib/src/upper/rlc_am.cc | 4 ++-- lib/src/upper/rlc_um.cc | 2 +- srsue/src/mac/mux.cc | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index e6e1ff279..5c7cb72ea 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -198,7 +198,7 @@ uint32_t rlc_am::get_bearer() void rlc_am::write_sdu(byte_buffer_t *sdu) { tx_sdu_queue.write(sdu); - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_queue_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size()); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); } /**************************************************************************** @@ -848,7 +848,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) // Set SN header.sn = vt_s; vt_s = (vt_s + 1)%MOD; - log->info("%s PDU scheduled for tx. SN: %d\n", rrc->get_rb_name(lcid).c_str(), header.sn); + log->info("%s PDU scheduled for tx. SN: %d (%d B)\n", rrc->get_rb_name(lcid).c_str(), header.sn, pdu->N_bytes); // Place PDU in tx_window, write header and TX tx_window[header.sn].buf = pdu; diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 647494552..6bbefaf78 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -173,7 +173,7 @@ uint32_t rlc_um::get_bearer() void rlc_um::write_sdu(byte_buffer_t *sdu) { tx_sdu_queue.write(sdu); - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size()); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (% B ,tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); } /**************************************************************************** diff --git a/srsue/src/mac/mux.cc b/srsue/src/mac/mux.cc index 59b94f085..33d048957 100644 --- a/srsue/src/mac/mux.cc +++ b/srsue/src/mac/mux.cc @@ -166,8 +166,7 @@ uint8_t* mux::pdu_get(uint8_t *payload, uint32_t pdu_sz, uint32_t tx_tti, uint32 } } -// Logical Channel Procedure - + // Logical Channel Procedure bool is_rar = false; pdu_msg.init_tx(payload, pdu_sz, true); @@ -325,7 +324,6 @@ bool mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_sz) if (pdu_msg->new_subh()) { // there is space for a new subheader sdu_len = pdu_msg->get()->set_sdu(lcid, sdu_len, rlc); if (sdu_len > 0) { // new SDU could be added - Debug("SDU: allocated lcid=%d, rlc_buffer=%d, allocated=%d/%d, max_sdu_sz=%d, remaining=%d\n", lcid, buffer_state, sdu_len, sdu_space, max_sdu_sz, pdu_msg->rem_size()); return true; From a0fff683f25163b8a2c2692245cfab95cea46d68 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 8 Mar 2018 14:39:01 +0100 Subject: [PATCH 32/70] Fixed pdsch_ue; it does not stop RF after cell search. --- lib/examples/pdsch_ue.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 74bac426d..fc99fdc9a 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -451,9 +451,6 @@ int main(int argc, char **argv) { exit(0); } - srslte_rf_stop_rx_stream(&rf); - srslte_rf_flush_buffer(&rf); - /* set sampling frequency */ int srate = srslte_sampling_freq_hz(cell.nof_prb); if (srate != -1) { From f3c04949b755ce135fef9488f213e3d7fed60b88 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 8 Mar 2018 16:56:51 +0100 Subject: [PATCH 33/70] PHCH Receive is reset, the current EARFCN becomes the first one in the list. --- srsue/src/phy/phch_recv.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 112cd03b8..7d6a2eec6 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -132,7 +132,11 @@ void phch_recv::reset() next_offset = 0; cell_is_set = false; srate_mode = SRATE_NONE; - current_earfcn = 0; + if (!earfcn.empty()) { + current_earfcn = earfcn[0]; + } else { + current_earfcn = 0; + } sfn_p.reset(); measure_p.reset(); search_p.reset(); From 9553784e2f5aa5c2839ca8ae70d23e4bf99531f3 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 17:55:48 +0100 Subject: [PATCH 34/70] change phy_log in UE to log_filter --- lib/include/srslte/common/log.h | 2 ++ srsue/hdr/phy/phy.h | 6 +++--- srsue/hdr/ue.h | 2 +- srsue/src/phy/phy.cc | 2 +- srsue/src/ue.cc | 3 +++ srsue/test/mac/mac_test.cc | 4 ++-- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/include/srslte/common/log.h b/lib/include/srslte/common/log.h index ff3a31eaa..360482c47 100644 --- a/lib/include/srslte/common/log.h +++ b/lib/include/srslte/common/log.h @@ -84,6 +84,8 @@ public: level_text_short = true; } + virtual ~log() {}; + // This function shall be called at the start of every tti for printing tti void step(uint32_t tti_) { tti = tti_; diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 0894a98fb..95140f8cd 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -28,7 +28,7 @@ #define UEPHY_H #include "srslte/srslte.h" -#include "srslte/common/log.h" +#include "srslte/common/log_filter.h" #include "phy/phy_metrics.h" #include "phy/phch_recv.h" #include "phy/prach.h" @@ -53,7 +53,7 @@ public: bool init(srslte::radio_multi *radio_handler, mac_interface_phy *mac, rrc_interface_phy *rrc, - std::vector log_vec, + std::vector log_vec, phy_args_t *args = NULL); void stop(); @@ -158,7 +158,7 @@ private: const static int WORKERS_THREAD_PRIO = 0; srslte::radio_multi *radio_handler; - std::vector log_vec; + std::vector log_vec; srslte::log *log_h; srslte::log *log_phy_lib_h; srsue::mac_interface_phy *mac; diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index d1343c68f..2aa7157e2 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -103,7 +103,7 @@ private: srslte::logger *logger; // rf_log is on ue_base - std::vector phy_log; + std::vector phy_log; srslte::log_filter mac_log; srslte::log_filter rlc_log; srslte::log_filter pdcp_log; diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index e4b618158..5c69d567d 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -120,7 +120,7 @@ bool phy::check_args(phy_args_t *args) } bool phy::init(srslte::radio_multi* radio_handler, mac_interface_phy *mac, rrc_interface_phy *rrc, - std::vector log_vec, phy_args_t *phy_args) { + std::vector log_vec, phy_args_t *phy_args) { mlockall(MCL_CURRENT | MCL_FUTURE); diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 381cb52bf..1d83f087e 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -44,6 +44,9 @@ ue::ue() ue::~ue() { + for (uint32_t i = 0; i < phy_log.size(); i++) { + delete(phy_log[i]); + } } bool ue::init(all_args_t *args_) diff --git a/srsue/test/mac/mac_test.cc b/srsue/test/mac/mac_test.cc index b76ab2f95..3d21720d4 100644 --- a/srsue/test/mac/mac_test.cc +++ b/srsue/test/mac/mac_test.cc @@ -451,12 +451,12 @@ int main(int argc, char *argv[]) exit(1); } - std::vector phy_log; + std::vector phy_log; srslte::log_filter *mylog = new srslte::log_filter("PHY"); char tmp[16]; sprintf(tmp, "PHY%d",0); - phy_log.push_back((srslte::log*) mylog); + phy_log.push_back(mylog); switch (prog_args.verbose) { case 1: From 44b1748a8752b61036333c39e83dcaa6239259aa Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 17:56:52 +0100 Subject: [PATCH 35/70] fix mem leak in sync --- lib/src/phy/sync/sync.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index c948a53d4..39bd98141 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -152,21 +152,19 @@ clean_exit: void srslte_sync_free(srslte_sync_t *q) { if (q) { - srslte_pss_free(&q->pss); srslte_sss_free(&q->sss); srslte_cfo_free(&q->cfo_corr_frame); srslte_cfo_free(&q->cfo_corr_symbol); srslte_cp_synch_free(&q->cp_synch); - if (q->cfo_i_initiated) { - for (int i=0;i<2;i++) { - if (q->cfo_i_corr[i]) { - free(q->cfo_i_corr[i]); - } - srslte_pss_free(&q->pss_i[i]); + for (int i = 0; i < 2; i++) { + if (q->cfo_i_corr[i]) { + free(q->cfo_i_corr[i]); } + srslte_pss_free(&q->pss_i[i]); } + if (q->temp) { free(q->temp); } From cbda94f0a6b9395084946db9ba5ea07e4917ebf2 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 17:58:11 +0100 Subject: [PATCH 36/70] fix mem leak in phch_recv --- srsue/hdr/phy/phch_recv.h | 2 ++ srsue/src/phy/phch_recv.cc | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index d77e489ae..7a04e4b10 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -199,6 +199,7 @@ private: uint32_t offset; } cell_info_t; void init(srslte::log *log_h, bool sic_pss_enabled, uint32_t max_sf_window); + void deinit(); void reset(); int find_cells(cf_t *input_buffer, float rx_gain_offset, srslte_cell_t current_cell, uint32_t nof_sf, cell_info_t found_cells[MAX_CELLS]); private: @@ -220,6 +221,7 @@ private: // Class to perform intra-frequency measurements class intra_measure : public thread { public: + ~intra_measure(); void init(phch_common *common, rrc_interface_phy *rrc, srslte::log *log_h); void stop(); void add_cell(int pci); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 7d6a2eec6..a96b9c545 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -711,6 +711,12 @@ void phch_recv::run_thread() mac->tti_clock(tti); tti = (tti+1) % 10240; } + + for (int i=0;icurrent_earfcn = earfcn; current_sflen = SRSLTE_SF_LEN_PRB(cell.nof_prb); From 43811e1886f73c7fcdd29fc56c75a63588fae6ad Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 18:00:35 +0100 Subject: [PATCH 37/70] deallocate used buffers in buffer_pool dtor --- lib/include/srslte/common/buffer_pool.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 035fbc661..76634a697 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -72,6 +72,10 @@ public: delete available.top(); available.pop(); } + + for (uint32_t i = 0; i < used.size(); i++) { + delete used[i]; + } } void print_all_buffers() From 5335f046ff6a0e42cf7c5b1860fd6f308e1aba46 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 8 Mar 2018 18:03:16 +0100 Subject: [PATCH 38/70] dealloc mutex and cond in msg_queue --- lib/include/srslte/common/msg_queue.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/include/srslte/common/msg_queue.h b/lib/include/srslte/common/msg_queue.h index bca4c5388..e8b8c742a 100644 --- a/lib/include/srslte/common/msg_queue.h +++ b/lib/include/srslte/common/msg_queue.h @@ -56,6 +56,9 @@ public: ~msg_queue() { + pthread_mutex_destroy(&mutex); + pthread_cond_destroy(¬_empty); + pthread_cond_destroy(¬_full); delete [] buf; } From b85a220145df84c7fb95c70f114849f2fe7f3b62 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 8 Mar 2018 16:35:37 -0500 Subject: [PATCH 39/70] Fix HO not setting serving cell --- srsue/src/upper/rrc.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index fdd461ebb..acb91e5fd 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -617,11 +617,6 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { int cell_idx = -1; bool found = true; - if (ho_syncing && phy_cell.id == ho_target_pci) { - ho_synced(ho_target_pci); - return; - } - pthread_mutex_lock(&mutex); if (serving_cell->equals(earfcn, phy_cell.id)) { @@ -665,6 +660,9 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { found?"Updating":"Adding", cell_idx>=0?"neighbour":"serving", earfcn, phy_cell.id, rsrp); + if (ho_syncing && phy_cell.id == ho_target_pci) { + ho_synced(ho_target_pci); + } } From 3afb93fcb9ad1ca42a407714b374d81b1efc01d9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 9 Mar 2018 17:05:46 +0100 Subject: [PATCH 40/70] exit the UE with q in console --- srsue/src/main.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/srsue/src/main.cc b/srsue/src/main.cc index ef38a7f80..f5df0af2d 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -422,6 +422,9 @@ void *input_loop(void *m) { cout << "Enter t to restart trace." << endl; } metrics_screen.toggle_print(do_metrics); + } else + if ('q' == key) { + running = false; } } } From 6ca6919694fc6b374c9e3ee710b066ed0fafaf16 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 11 Mar 2018 21:47:15 -0400 Subject: [PATCH 41/70] Handle T300 expiry to avoid blocking on RLC TM UL CCCH when ConnectionRequest fails --- srsue/hdr/upper/rrc.h | 2 +- srsue/src/upper/rrc.cc | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 8d092051a..5c9899eab 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -341,7 +341,7 @@ private: srslte::mac_interface_timers *mac_timers; uint32_t n310_cnt, N310; uint32_t n311_cnt, N311; - uint32_t t301, t310, t311, t304; + uint32_t t300, t301, t310, t311, t304; // Radio bearers typedef enum{ diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index acb91e5fd..1f0c6eb94 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -113,6 +113,7 @@ void rrc::init(phy_interface_rrc *phy_, args.nof_supported_bands = 1; args.feature_group = 0xe6041c00; + t300 = mac_timers->timer_get_unique_id(); t301 = mac_timers->timer_get_unique_id(); t310 = mac_timers->timer_get_unique_id(); t311 = mac_timers->timer_get_unique_id(); @@ -930,6 +931,13 @@ void rrc::timer_expired(uint32_t timeout_id) { } else if (timeout_id == t311) { rrc_log->info("Timer T311 expired: Going to RRC IDLE\n"); state = RRC_STATE_LEAVE_CONNECTED; + } else if (timeout_id == t300) { + rrc_log->info("Timer T300 expired: ConnectionRequest failed. Reset MAC and restablished RLC.\n"); + rlc->reestablish(); + mac->reset(); + set_mac_default(); + state = RRC_STATE_IDLE; + nas->plmn_search_end(); } else if (timeout_id == t301) { if (state == RRC_STATE_IDLE) { rrc_log->info("Timer T301 expired: Already in IDLE.\n"); @@ -985,6 +993,8 @@ void rrc::send_con_request() { ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING; + mac_timers->timer_get(t300)->reset(); + mac_timers->timer_get(t300)->run(); send_ul_ccch_msg(); } @@ -1676,6 +1686,8 @@ void rrc::parse_dl_ccch(byte_buffer_t *pdu) { case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REJ: rrc_log->info("Connection Reject received. Wait time: %d\n", dl_ccch_msg.msg.rrc_con_rej.wait_time); + // Stop T300 timer + mac_timers->timer_get(t300)->stop(); state = RRC_STATE_LEAVE_CONNECTED; break; case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_SETUP: @@ -1978,14 +1990,15 @@ void rrc::apply_sib2_configs(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2) { liblte_rrc_srs_subfr_config_num[sib2->rr_config_common_sib.srs_ul_cnfg.subfr_cnfg], sib2->rr_config_common_sib.srs_ul_cnfg.ack_nack_simul_tx ? "yes" : "no"); + mac_timers->timer_get(t300)->set(this, liblte_rrc_t300_num[sib2->ue_timers_and_constants.t300]); mac_timers->timer_get(t301)->set(this, liblte_rrc_t301_num[sib2->ue_timers_and_constants.t301]); mac_timers->timer_get(t310)->set(this, liblte_rrc_t310_num[sib2->ue_timers_and_constants.t310]); mac_timers->timer_get(t311)->set(this, liblte_rrc_t311_num[sib2->ue_timers_and_constants.t311]); N310 = liblte_rrc_n310_num[sib2->ue_timers_and_constants.n310]; N311 = liblte_rrc_n311_num[sib2->ue_timers_and_constants.n311]; - rrc_log->info("Set Constants and Timers: N310=%d, N311=%d, t301=%d, t310=%d, t311=%d\n", - N310, N311, mac_timers->timer_get(t301)->get_timeout(), + rrc_log->info("Set Constants and Timers: N310=%d, N311=%d, t300=%d, t301=%d, t310=%d, t311=%d\n", + N310, N311, mac_timers->timer_get(t300)->get_timeout(), mac_timers->timer_get(t301)->get_timeout(), mac_timers->timer_get(t310)->get_timeout(), mac_timers->timer_get(t311)->get_timeout()); } @@ -2222,6 +2235,10 @@ void rrc::apply_rr_config_dedicated(LIBLTE_RRC_RR_CONFIG_DEDICATED_STRUCT *cnfg) } void rrc::handle_con_setup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *setup) { + + // Stop T300 timer + mac_timers->timer_get(t300)->stop(); + // Apply the Radio Resource configuration apply_rr_config_dedicated(&setup->rr_cnfg); } From 8bda956330794a96e407394f7275e5652762fa57 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 13 Mar 2018 01:01:53 +0100 Subject: [PATCH 42/70] Solved logging error trace --- srsue/src/phy/phch_worker.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 8a6c5cd8b..12e717b9a 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -574,7 +574,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) last_dl_pdcch_ncce = srslte_ue_dl_get_ncce(&ue_dl); - char hexstr[16]; + char hexstr[SRSLTE_DCI_MAX_BITS/8]; hexstr[0]='\0'; if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); @@ -812,7 +812,7 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) grant->has_cqi_request = dci_unpacked.cqi_request; ret = true; - char hexstr[16]; + char hexstr[SRSLTE_DCI_MAX_BITS/8]; hexstr[0]='\0'; if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); From c2098ad6260ee3c772c26f404314fe01c4bc5f18 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Mar 2018 18:52:21 +0100 Subject: [PATCH 43/70] Removed unused sample offset correction --- lib/include/srslte/interfaces/ue_interfaces.h | 3 +- lib/include/srslte/phy/ue/ue_dl.h | 7 ----- lib/src/phy/ue/ue_dl.c | 30 +------------------ srsue/hdr/phy/phch_worker.h | 3 +- srsue/src/main.cc | 4 --- srsue/src/phy/phch_recv.cc | 2 -- srsue/src/phy/phch_worker.cc | 8 ----- srsue/src/phy/phy.cc | 3 +- 8 files changed, 4 insertions(+), 56 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 75acc27ea..9a7a68a34 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -487,8 +487,7 @@ typedef struct { uint32_t cfo_ref_mask; bool average_subframe_enabled; int time_correct_period; - bool sfo_correct_disable; - std::string sss_algorithm; + std::string sss_algorithm; float estimator_fil_w; bool rssi_sensor_enabled; bool sic_pss_enabled; diff --git a/lib/include/srslte/phy/ue/ue_dl.h b/lib/include/srslte/phy/ue/ue_dl.h index 6974a0b99..c5b0da52a 100644 --- a/lib/include/srslte/phy/ue/ue_dl.h +++ b/lib/include/srslte/phy/ue/ue_dl.h @@ -84,8 +84,6 @@ typedef struct SRSLTE_API { srslte_ofdm_t fft_mbsfn; srslte_chest_dl_t chest; - srslte_cfo_t sfo_correct; - srslte_pdsch_cfg_t pdsch_cfg; srslte_pdsch_cfg_t pmch_cfg; srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS]; @@ -126,8 +124,6 @@ typedef struct SRSLTE_API { srslte_dci_msg_t pending_ul_dci_msg; uint16_t pending_ul_dci_rnti; - float sample_offset; - float last_phich_corr; }srslte_ue_dl_t; @@ -195,9 +191,6 @@ SRSLTE_API int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, SRSLTE_API uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q); -SRSLTE_API void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, - float sample_offset); - SRSLTE_API int srslte_ue_dl_decode(srslte_ue_dl_t *q, uint8_t *data[SRSLTE_MAX_CODEWORDS], uint32_t tm, diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 3815041a7..98ff5c9fd 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -71,7 +71,6 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, q->pmch_pkt_errors = 0; q->pmch_pkts_total = 0; q->pending_ul_dci_rnti = 0; - q->sample_offset = 0; q->nof_rx_antennas = nof_rx_antennas; for (int j = 0; j < SRSLTE_MAX_PORTS; j++) { @@ -147,12 +146,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, goto clean_exit; } } - if (srslte_cfo_init(&q->sfo_correct, max_prb*SRSLTE_NRE)) { - fprintf(stderr, "Error initiating SFO correct\n"); - goto clean_exit; - } - srslte_cfo_set_tol(&q->sfo_correct, 1e-5f/q->fft[0].symbol_sz); - + ret = SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid parametres\n"); @@ -178,7 +172,6 @@ void srslte_ue_dl_free(srslte_ue_dl_t *q) { srslte_pdcch_free(&q->pdcch); srslte_pdsch_free(&q->pdsch); srslte_pmch_free(&q->pmch); - srslte_cfo_free(&q->sfo_correct); for (int i = 0; i < SRSLTE_MAX_TB; i++) { srslte_softbuffer_rx_free(q->softbuffers[i]); if (q->softbuffers[i]) { @@ -209,7 +202,6 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t *q, srslte_cell_t cell) q->pkt_errors = 0; q->pkts_total = 0; q->pending_ul_dci_rnti = 0; - q->sample_offset = 0; if (q->cell.id != cell.id || q->cell.nof_prb == 0) { if (q->cell.nof_prb != 0) { @@ -220,11 +212,6 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t *q, srslte_cell_t cell) fprintf(stderr, "Error resizing REGs\n"); return SRSLTE_ERROR; } - if (srslte_cfo_resize(&q->sfo_correct, q->cell.nof_prb*SRSLTE_NRE)) { - fprintf(stderr, "Error resizing SFO correct\n"); - return SRSLTE_ERROR; - } - srslte_cfo_set_tol(&q->sfo_correct, 1e-5f/q->fft[0].symbol_sz); for (int port = 0; port < q->nof_rx_antennas; port++) { if (srslte_ofdm_rx_set_prb(&q->fft[port], q->cell.cp, q->cell.nof_prb)) { fprintf(stderr, "Error resizing FFT\n"); @@ -348,10 +335,6 @@ void srslte_ue_dl_reset(srslte_ue_dl_t *q) { bzero(&q->pdsch_cfg, sizeof(srslte_pdsch_cfg_t)); } -void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, float sample_offset) { - q->sample_offset = sample_offset; -} - /** Applies the following operations to a subframe of synchronized samples: * - OFDM demodulation * - Channel estimation @@ -395,17 +378,6 @@ int srslte_ue_dl_decode_fft_estimate_noguru(srslte_ue_dl_t *q, cf_t *input[SRSLT /* Run FFT for all subframe data */ for (int j=0;jnof_rx_antennas;j++) { srslte_ofdm_rx_sf_ng(&q->fft[j], input[j], q->sf_symbols_m[j]); - - /* Correct SFO multiplying by complex exponential in the time domain */ - if (q->sample_offset) { - int nsym = SRSLTE_CP_NSYMB(q->cell.cp); - for (int i=0;i<2*nsym;i++) { - srslte_cfo_correct(&q->sfo_correct, - &q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE], - &q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE], - q->sample_offset / q->fft[j].symbol_sz); - } - } } return srslte_ue_dl_decode_estimate_mbsfn(q, sf_idx, cfi, SRSLTE_SF_NORM); } else { diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 167334918..6f72285b2 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -54,8 +54,7 @@ public: void set_tti(uint32_t tti, uint32_t tx_tti); void set_tx_time(srslte_timestamp_t tx_time, uint32_t next_offset); void set_cfo(float cfo); - void set_sample_offset(float sample_offset); - + void set_ul_params(bool pregen_disabled = false); void set_crnti(uint16_t rnti); void enable_pregen_signals(bool enabled); diff --git a/srsue/src/main.cc b/srsue/src/main.cc index f5df0af2d..d2d029c63 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -258,10 +258,6 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.time_correct_period)->default_value(5), "Period for sampling time offset correction.") - ("expert.sfo_correct_disable", - bpo::value(&args->expert.phy.sfo_correct_disable)->default_value(false), - "Disables phase correction before channel estimation.") - ("expert.sss_algorithm", bpo::value(&args->expert.phy.sss_algorithm)->default_value("full"), "Selects the SSS estimation algorithm.") diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index a96b9c545..850294175 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -636,8 +636,6 @@ void phch_recv::run_thread() worker->set_cfo(ul_dl_factor * metrics.cfo / 15000); worker_com->set_sync_metrics(metrics); - worker->set_sample_offset(srslte_ue_sync_get_sfo(&ue_sync)/1000); - /* Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time */ srslte_timestamp_t rx_time, tx_time, tx_time_prach; srslte_ue_sync_get_last_timestamp(&ue_sync, &rx_time); diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 8a6c5cd8b..32f336f59 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -190,14 +190,6 @@ void phch_worker::set_cfo(float cfo_) cfo = cfo_; } -void phch_worker::set_sample_offset(float sample_offset) -{ - if (phy->args->sfo_correct_disable) { - sample_offset = 0; - } - srslte_ue_dl_set_sample_offset(&ue_dl, sample_offset); -} - void phch_worker::set_crnti(uint16_t rnti) { srslte_ue_dl_set_rnti(&ue_dl, rnti); diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 5c69d567d..27b389a4e 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -97,8 +97,7 @@ void phy::set_default_args(phy_args_t *args) args->cfo_integer_enabled = false; args->cfo_correct_tol_hz = 50; args->time_correct_period = 5; - args->sfo_correct_disable = false; - args->sss_algorithm = "full"; + args->sss_algorithm = "full"; args->estimator_fil_w = 0.1; } From 809c550ca2dd0ebae0e1632abc3330004b2c5e2e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Mar 2018 19:07:15 +0100 Subject: [PATCH 44/70] Use RS power estimation for serving cell RSRP/SNR measurements. Use correlation of RS sequences for neighbour cell verification of Cell ID --- .../srslte/phy/ch_estimation/chest_dl.h | 10 ++- lib/src/phy/ch_estimation/chest_dl.c | 42 +++++++++-- srsue/hdr/phy/phch_recv.h | 3 +- srsue/src/phy/phch_recv.cc | 72 ++++++++++++------- 4 files changed, 96 insertions(+), 31 deletions(-) diff --git a/lib/include/srslte/phy/ch_estimation/chest_dl.h b/lib/include/srslte/phy/ch_estimation/chest_dl.h index c1f5579a1..e7cc28bed 100644 --- a/lib/include/srslte/phy/ch_estimation/chest_dl.h +++ b/lib/include/srslte/phy/ch_estimation/chest_dl.h @@ -82,10 +82,13 @@ typedef struct { srslte_interp_lin_t srslte_interp_lin_3; srslte_interp_lin_t srslte_interp_lin_mbsfn; float rssi[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; - float rsrp[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; + float rsrp[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; + float rsrp_corr[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; float noise_estimate[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; float cfo; + bool rsrp_neighbour; + bool cfo_estimate_enable; uint32_t cfo_estimate_sf_mask; @@ -158,6 +161,9 @@ SRSLTE_API void srslte_chest_dl_cfo_estimate_enable(srslte_chest_dl_t *q, SRSLTE_API void srslte_chest_dl_average_subframe(srslte_chest_dl_t *q, bool enable); +SRSLTE_API void srslte_chest_dl_set_rsrp_neighbour(srslte_chest_dl_t *q, + bool rsrp_for_neighbour); + SRSLTE_API float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q); SRSLTE_API float srslte_chest_dl_get_cfo(srslte_chest_dl_t *q); @@ -185,4 +191,6 @@ SRSLTE_API float srslte_chest_dl_get_rsrp_port(srslte_chest_dl_t *q, SRSLTE_API float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q); +SRSLTE_API float srslte_chest_dl_get_rsrp_neighbour(srslte_chest_dl_t *q); + #endif diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index ec827ec13..8d9125910 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -152,7 +152,9 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, uint32_t max_prb) } q->noise_alg = SRSLTE_NOISE_ALG_REFS; - + + q->rsrp_neighbour = false; + q->smooth_filter_len = 3; srslte_chest_dl_set_smooth_filter3_coeff(q, 0.1); @@ -545,7 +547,7 @@ void chest_interpolate_noise_est(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, ui } } -int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id) +int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id) { uint32_t npilots = SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id); @@ -557,14 +559,18 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u q->pilot_estimates, npilots); /* Compute RSRP for the channel estimates in this port */ - double energy = cabs(srslte_vec_acc_cc(q->pilot_estimates, npilots)/npilots); - q->rsrp[rxant_id][port_id] = energy*energy; + if (q->rsrp_neighbour) { + double energy = cabs(srslte_vec_acc_cc(q->pilot_estimates, npilots)/npilots); + q->rsrp_corr[rxant_id][port_id] = energy*energy; + } + q->rsrp[rxant_id][port_id] = srslte_vec_avg_power_cf(q->pilot_recv_signal, npilots); q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id); chest_interpolate_noise_est(q, input, ce, sf_idx, port_id, rxant_id, SRSLTE_SF_NORM); return 0; } + int srslte_chest_dl_estimate_port_mbsfn(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id, uint16_t mbsfn_area_id) { @@ -623,6 +629,10 @@ int srslte_chest_dl_estimate_multi_mbsfn(srslte_chest_dl_t *q, cf_t *input[SRSLT return SRSLTE_SUCCESS; } +void srslte_chest_dl_set_rsrp_neighbour(srslte_chest_dl_t *q, bool rsrp_for_neighbour) { + q->rsrp_neighbour = rsrp_for_neighbour; +} + void srslte_chest_dl_average_subframe(srslte_chest_dl_t *q, bool enable) { q->average_subframe = enable; @@ -710,6 +720,19 @@ float srslte_chest_dl_get_rsrp_port(srslte_chest_dl_t *q, uint32_t port) { return sum; } +float srslte_chest_dl_get_rsrp_neighbour_port(srslte_chest_dl_t *q, uint32_t port) { + float sum = 0.0f; + for (int j = 0; j < q->cell.nof_ports; ++j) { + sum +=q->rsrp_corr[port][j]; + } + + if (q->cell.nof_ports) { + sum /= q->cell.nof_ports; + } + + return sum; +} + float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { float max = -0.0f; for (int i = 0; i < q->last_nof_antennas; ++i) { @@ -720,3 +743,14 @@ float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { } return max; } + +float srslte_chest_dl_get_rsrp_neighbour(srslte_chest_dl_t *q) { + float max = -0.0f; + for (int i = 0; i < q->last_nof_antennas; ++i) { + float v = srslte_chest_dl_get_rsrp_neighbour_port(q, i); + if (v > max) { + max = v; + } + } + return max; +} diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 7a04e4b10..3d00b631b 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -171,6 +171,7 @@ private: ret_code run_multiple_subframes(cf_t *buffer, uint32_t offset, uint32_t sf_idx, uint32_t nof_sf); float rssi(); float rsrp(); + float rsrp_n(); float rsrq(); float snr(); uint32_t frame_st_idx(); @@ -183,7 +184,7 @@ private: uint32_t nof_subframes; uint32_t current_prb; float rx_gain_offset; - float mean_rsrp, mean_rsrq, mean_snr, mean_rssi; + float mean_rsrp, mean_rsrp_n, mean_rsrq, mean_snr, mean_rssi; uint32_t final_offset; const static int RSRP_MEASURE_NOF_FRAMES = 5; }; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 850294175..6ec87d2fa 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1022,6 +1022,7 @@ void phch_recv::measure::init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h Error("SYNC: Initiating ue_dl_measure\n"); return; } + srslte_chest_dl_set_rsrp_neighbour(&ue_dl.chest, true); reset(); } @@ -1054,6 +1055,10 @@ float phch_recv::measure::rsrp() { return 10*log10(mean_rsrp) + 30 - rx_gain_offset; } +float phch_recv::measure::rsrp_n() { + return 10*log10(mean_rsrp_n) + 30 - rx_gain_offset; +} + float phch_recv::measure::rsrq() { return 10*log10(mean_rsrq); } @@ -1099,12 +1104,13 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in sf_idx ++; } + + // Fine-tune offset using RS +#ifdef FINE_TUNE_OFFSET_WITH_RS float max_rsrp = -200; int best_test_offset = 0; int test_offset = 0; bool found_best = false; - - // Fine-tune offset using RS for (uint32_t n=0;n<5;n++) { test_offset = offset-2+n; @@ -1128,11 +1134,14 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in } } + Debug("INTRA: fine-tuning offset: %d, found_best=%d, rem_sf=%d\n", offset, found_best, nof_sf); + offset = found_best?best_test_offset:offset; +#endif + if (offset >= 0 && offset < sf_len*max_sf) { uint32_t nof_sf = (sf_len*max_sf - offset)/sf_len; - Debug("INTRA: fine-tuning offset: %d, found_best=%d, rem_sf=%d\n", offset, found_best, nof_sf); final_offset = offset; @@ -1161,25 +1170,28 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) } float rsrp = srslte_chest_dl_get_rsrp(&ue_dl.chest); + float rsrp_n = srslte_chest_dl_get_rsrp_neighbour(&ue_dl.chest); float rsrq = srslte_chest_dl_get_rsrq(&ue_dl.chest); float snr = srslte_chest_dl_get_snr(&ue_dl.chest); float rssi = srslte_vec_avg_power_cf(buffer[0], SRSLTE_SF_LEN_PRB(current_prb)); if (cnt == 0) { - mean_rsrp = rsrp; - mean_rsrq = rsrq; - mean_snr = snr; - mean_rssi = rssi; + mean_rsrp = rsrp; + mean_rsrp_n = rsrp_n; + mean_rsrq = rsrq; + mean_snr = snr; + mean_rssi = rssi; } else { - mean_rsrp = SRSLTE_VEC_CMA(rsrp, mean_rsrp, cnt); - mean_rsrq = SRSLTE_VEC_CMA(rsrq, mean_rsrq, cnt); - mean_snr = SRSLTE_VEC_CMA(snr, mean_snr, cnt); - mean_rssi = SRSLTE_VEC_CMA(rssi, mean_rssi, cnt); + mean_rsrp = SRSLTE_VEC_CMA(rsrp, mean_rsrp, cnt); + mean_rsrp_n = SRSLTE_VEC_CMA(rsrp_n, mean_rsrp_n, cnt); + mean_rsrq = SRSLTE_VEC_CMA(rsrq, mean_rsrq, cnt); + mean_snr = SRSLTE_VEC_CMA(snr, mean_snr, cnt); + mean_rssi = SRSLTE_VEC_CMA(rssi, mean_rssi, cnt); } cnt++; - log_h->debug("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, SNR=%.1f dB\n", - cnt, nof_subframes, sf_idx, rsrp, snr); + log_h->debug("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, corr-RSRP=%.1f dBm, SNR=%.1f dB\n", + cnt, nof_subframes, sf_idx, rsrp, rsrp_n, snr); if (cnt >= nof_subframes) { return MEASURE_OK; @@ -1217,6 +1229,7 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3 fprintf(stderr, "Error initiating sync_find\n"); return; } + srslte_sync_set_sss_algorithm(&sync_find, SSS_FULL); srslte_sync_cp_en(&sync_find, false); srslte_sync_set_cfo_pss_enable(&sync_find, true); srslte_sync_set_threshold(&sync_find, 1.7); @@ -1230,8 +1243,7 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3 srslte_sync_set_sss_eq_enable(&sync_find, true); sync_find.pss.chest_on_filter = true; - - sync_find.sss_channel_equalize = true; + sync_find.sss_channel_equalize = false; reset(); } @@ -1336,17 +1348,27 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, case measure::MEASURE_OK: // Consider a cell to be detectable 8.1.2.2.1.1 from 36.133. Currently only using first condition if (measure_p.rsrp() > ABSOLUTE_RSRP_THRESHOLD_DBM) { - cells[nof_cells].pci = found_cell.id; - cells[nof_cells].rsrp = measure_p.rsrp(); - cells[nof_cells].rsrq = measure_p.rsrq(); - cells[nof_cells].offset = measure_p.frame_st_idx(); - - Info( - "INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", - nof_cells, cell_id, measure_p.rsrp(), measure_p.frame_st_idx(), sync_find.peak_value, - sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); - nof_cells++; + // Check the cell id has been correctly identified by using the correlation of the RS sequences + // By experimentation, typically the cross-correlation is ~3/4 dB less + if (measure_p.rsrp_n() > measure_p.rsrp() - 6) { + cells[nof_cells].pci = found_cell.id; + cells[nof_cells].rsrp = measure_p.rsrp(); + cells[nof_cells].rsrq = measure_p.rsrq(); + cells[nof_cells].offset = measure_p.frame_st_idx(); + + Info( + "INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, corr-RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", + nof_cells, cell_id, measure_p.rsrp(), measure_p.rsrp_n(), measure_p.frame_st_idx(), sync_find.peak_value, + sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); + + nof_cells++; + } else { + Info( + "INTRA: Found phantom cell %d: PCI=%03d, RSRP=%5.1f dBm, corr-RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", + nof_cells, cell_id, measure_p.rsrp(), measure_p.rsrp_n(), measure_p.frame_st_idx(), sync_find.peak_value, + sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); + } /* if (sic_pss_enabled) { From b77e3b0be56114958eda79747ab5be0f63c0db5d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Mar 2018 20:01:09 +0100 Subject: [PATCH 45/70] Avoid negative offset in neighbour cell search --- srsue/src/phy/phch_recv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 6ec87d2fa..b186e0ae1 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1099,7 +1099,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in ret_code ret = IDLE; offset = offset-sf_len/2; - if (offset < 0) { + while (offset < 0) { offset += sf_len; sf_idx ++; } From 0fbeee72a17ce420a0036f2680e530a97a469517 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 13 Mar 2018 20:47:31 +0100 Subject: [PATCH 46/70] Fixed offset int in previous commit --- srsue/hdr/phy/phch_recv.h | 2 +- srsue/src/phy/phch_recv.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 3d00b631b..8b87f0521 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -168,7 +168,7 @@ private: void set_cell(srslte_cell_t cell); ret_code run_subframe(uint32_t sf_idx); ret_code run_subframe_sync(srslte_ue_sync_t *ue_sync, uint32_t sf_idx); - ret_code run_multiple_subframes(cf_t *buffer, uint32_t offset, uint32_t sf_idx, uint32_t nof_sf); + ret_code run_multiple_subframes(cf_t *buffer, int offset, uint32_t sf_idx, uint32_t nof_sf); float rssi(); float rsrp(); float rsrp_n(); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index b186e0ae1..2799cb999 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1090,7 +1090,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe_sync(srslte_ue_syn } phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *input_buffer, - uint32_t offset, + int offset, uint32_t sf_idx, uint32_t max_sf) { @@ -1099,7 +1099,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in ret_code ret = IDLE; offset = offset-sf_len/2; - while (offset < 0) { + while (offset < 0 && sf_idx < max_sf) { offset += sf_len; sf_idx ++; } From 33ebde5387ce652d39bc7506400c05ae129018cc Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 09:53:48 +0100 Subject: [PATCH 47/70] Fixed bug SIB3 loop and window_start 10s wait in disconnect --- srsue/src/phy/phch_recv.cc | 2 +- srsue/src/upper/rrc.cc | 33 +++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 2799cb999..9d539a02d 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1139,7 +1139,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in offset = found_best?best_test_offset:offset; #endif - if (offset >= 0 && offset < sf_len*max_sf) { + if (offset >= 0 && offset < (int) sf_len*max_sf) { uint32_t nof_sf = (sf_len*max_sf - offset)/sf_len; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 1f0c6eb94..8c346bfaa 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -98,6 +98,7 @@ void rrc::init(phy_interface_rrc *phy_, mac_timers = mac_timers_; state = RRC_STATE_IDLE; si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; ho_syncing = false; @@ -178,10 +179,6 @@ void rrc::run_thread() { while (thread_running) { - if (state >= RRC_STATE_IDLE && state < RRC_STATE_CONNECTING) { - run_si_acquisition_procedure(); - } - switch(state) { /* Procedures in IDLE state 36.304 Sec 4 */ case RRC_STATE_IDLE: @@ -232,13 +229,16 @@ void rrc::run_thread() { si_acquire_state = SI_ACQUIRE_SIB2; } else { apply_sib2_configs(serving_cell->sib2ptr()); - si_acquire_state = SI_ACQUIRE_IDLE; state = RRC_STATE_CELL_SELECTED; } + run_si_acquisition_procedure(); } break; case RRC_STATE_CELL_SELECTED: + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; + /* The cell is selected when the SIBs are received and applied. * If we were in RRC_CONNECTED and arrive here it means a RLF occurred and we are in Reestablishment procedure. * If T311 is running means there is a reestablishment in progress, send ConnectionReestablishmentRequest. @@ -267,6 +267,8 @@ void rrc::run_thread() { if (connecting_timeout >= RRC_CONNECTING_TIMEOUT) { // Select another cell rrc_log->info("RRC Connecting: timeout expired. Selecting next cell\n"); + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; state = RRC_STATE_CELL_SELECTING; } break; @@ -358,6 +360,7 @@ void rrc::run_si_acquisition_procedure() if (state == RRC_STATE_CELL_SELECTING) { select_next_cell_in_plmn(); si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; } else if (state == RRC_STATE_PLMN_SELECTION) { phy->cell_search_next(); } @@ -384,13 +387,14 @@ void rrc::run_si_acquisition_procedure() last_win_start = si_win_start; mac->bcch_start_rx(si_win_start, si_win_len); - rrc_log->debug("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", - si_win_start, si_win_len); + rrc_log->info("Instructed MAC to search for system info=%d, win_start=%d, win_len=%d\n", + sysinfo_index, si_win_start, si_win_len); } } else { // We've received all SIBs, move on to connection request si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; state = RRC_STATE_CELL_SELECTED; } break; @@ -477,6 +481,8 @@ void rrc::plmn_select_rrc(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { } } + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; state = RRC_STATE_CELL_SELECTING; } else { rrc_log->warning("Requested PLMN select in incorrect state %s\n", rrc_state_text[state]); @@ -549,6 +555,8 @@ bool rrc::select_next_cell_in_plmn() { rrc_log->console("Selected cell PCI=%d, EARFCN=%d\n", serving_cell->phy_cell.id, serving_cell->get_earfcn()); phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; state = RRC_STATE_CELL_SELECTING; return true; } @@ -644,9 +652,7 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { pthread_mutex_unlock(&mutex); - if (!serving_cell->has_sib1()) { - si_acquire_state = SI_ACQUIRE_SIB1; - } else if (state == RRC_STATE_PLMN_SELECTION) { + if (state == RRC_STATE_PLMN_SELECTION && serving_cell->has_sib1()) { bool ret = false; for (uint32_t j = 0; j < serving_cell->sib1ptr()->N_plmn_ids; j++) { ret |= nas->plmn_found(serving_cell->sib1ptr()->plmn_id[j].id, serving_cell->sib1ptr()->tracking_area_code); @@ -655,6 +661,8 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { if (!ret) { phy->cell_search_next(); } + } else if (!ho_syncing) { + state = RRC_STATE_CELL_SELECTING; } rrc_log->info("%s %s cell EARFCN=%d, PCI=%d, RSRP=%.1f dBm\n", @@ -1062,6 +1070,8 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, mac->reset(); set_mac_default(); phy->sync_reset(); + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; state = RRC_STATE_CELL_SELECTING; } @@ -1347,6 +1357,8 @@ void rrc::leave_connected() { rrc_log->console("RRC IDLE\n"); rrc_log->info("Leaving RRC_CONNECTED state\n"); + si_acquire_state = SI_ACQUIRE_IDLE; + last_win_start = 0; drb_up = false; measurements.reset(); pdcp->reset(); @@ -1424,6 +1436,7 @@ void rrc::write_pdu_bcch_dlsch(byte_buffer_t *pdu) { if(serving_cell->has_sib2()) { sysinfo_index++; + rrc_log->info("Increasing sysinfo_index=%d\n", sysinfo_index); } } From c815051238657aa361c76da6916d3bcafa2b708d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 10:22:44 +0100 Subject: [PATCH 48/70] Increased str buffer for DCI printing --- srsue/src/phy/phch_worker.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 0f2e75920..b3a33ea6c 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -566,7 +566,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) last_dl_pdcch_ncce = srslte_ue_dl_get_ncce(&ue_dl); - char hexstr[SRSLTE_DCI_MAX_BITS/8]; + char hexstr[512]; hexstr[0]='\0'; if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); @@ -804,7 +804,7 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) grant->has_cqi_request = dci_unpacked.cqi_request; ret = true; - char hexstr[SRSLTE_DCI_MAX_BITS/8]; + char hexstr[512]; hexstr[0]='\0'; if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { srslte_vec_sprint_hex(hexstr, sizeof(hexstr), dci_msg.data, dci_msg.nof_bits); From c0aea5ae13bf89eaa83ff892dc595bdd8446c972 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 10:23:05 +0100 Subject: [PATCH 49/70] Neighbour cell RSRP measurement always and only with correlation method --- lib/src/phy/ch_estimation/chest_dl.c | 4 +-- srsue/hdr/phy/phch_recv.h | 6 ++-- srsue/src/phy/phch_recv.cc | 52 +++++++--------------------- 3 files changed, 17 insertions(+), 45 deletions(-) diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 8d9125910..e719b22c0 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -734,7 +734,7 @@ float srslte_chest_dl_get_rsrp_neighbour_port(srslte_chest_dl_t *q, uint32_t por } float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { - float max = -0.0f; + float max = -1e9; for (int i = 0; i < q->last_nof_antennas; ++i) { float v = srslte_chest_dl_get_rsrp_port(q, i); if (v > max) { @@ -745,7 +745,7 @@ float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { } float srslte_chest_dl_get_rsrp_neighbour(srslte_chest_dl_t *q) { - float max = -0.0f; + float max = -1e9; for (int i = 0; i < q->last_nof_antennas; ++i) { float v = srslte_chest_dl_get_rsrp_neighbour_port(q, i); if (v > max) { diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 8b87f0521..d71bcb1d5 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -171,7 +171,6 @@ private: ret_code run_multiple_subframes(cf_t *buffer, int offset, uint32_t sf_idx, uint32_t nof_sf); float rssi(); float rsrp(); - float rsrp_n(); float rsrq(); float snr(); uint32_t frame_st_idx(); @@ -184,7 +183,7 @@ private: uint32_t nof_subframes; uint32_t current_prb; float rx_gain_offset; - float mean_rsrp, mean_rsrp_n, mean_rsrq, mean_snr, mean_rssi; + float mean_rsrp, mean_rsrq, mean_snr, mean_rssi; uint32_t final_offset; const static int RSRP_MEASURE_NOF_FRAMES = 5; }; @@ -205,7 +204,6 @@ private: int find_cells(cf_t *input_buffer, float rx_gain_offset, srslte_cell_t current_cell, uint32_t nof_sf, cell_info_t found_cells[MAX_CELLS]); private: - cf_t *input_cfo_corrected; cf_t *sf_buffer[SRSLTE_MAX_PORTS]; srslte::log *log_h; srslte_sync_t sync_find; @@ -233,7 +231,7 @@ private: void write(uint32_t tti, cf_t *data, uint32_t nsamples); private: void run_thread(); - const static int INTRA_FREQ_MEAS_LEN_MS = 50; + const static int INTRA_FREQ_MEAS_LEN_MS = 20; const static int INTRA_FREQ_MEAS_PERIOD_MS = 200; const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 9d539a02d..456f14ea0 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1055,10 +1055,6 @@ float phch_recv::measure::rsrp() { return 10*log10(mean_rsrp) + 30 - rx_gain_offset; } -float phch_recv::measure::rsrp_n() { - return 10*log10(mean_rsrp_n) + 30 - rx_gain_offset; -} - float phch_recv::measure::rsrq() { return 10*log10(mean_rsrq); } @@ -1169,21 +1165,18 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) return ERROR; } - float rsrp = srslte_chest_dl_get_rsrp(&ue_dl.chest); - float rsrp_n = srslte_chest_dl_get_rsrp_neighbour(&ue_dl.chest); + float rsrp = srslte_chest_dl_get_rsrp_neighbour(&ue_dl.chest); float rsrq = srslte_chest_dl_get_rsrq(&ue_dl.chest); float snr = srslte_chest_dl_get_snr(&ue_dl.chest); float rssi = srslte_vec_avg_power_cf(buffer[0], SRSLTE_SF_LEN_PRB(current_prb)); if (cnt == 0) { mean_rsrp = rsrp; - mean_rsrp_n = rsrp_n; mean_rsrq = rsrq; mean_snr = snr; mean_rssi = rssi; } else { mean_rsrp = SRSLTE_VEC_CMA(rsrp, mean_rsrp, cnt); - mean_rsrp_n = SRSLTE_VEC_CMA(rsrp_n, mean_rsrp_n, cnt); mean_rsrq = SRSLTE_VEC_CMA(rsrq, mean_rsrq, cnt); mean_snr = SRSLTE_VEC_CMA(snr, mean_snr, cnt); mean_rssi = SRSLTE_VEC_CMA(rssi, mean_rssi, cnt); @@ -1191,7 +1184,7 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) cnt++; log_h->debug("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, corr-RSRP=%.1f dBm, SNR=%.1f dB\n", - cnt, nof_subframes, sf_idx, rsrp, rsrp_n, snr); + cnt, nof_subframes, sf_idx, rsrp, snr); if (cnt >= nof_subframes) { return MEASURE_OK; @@ -1220,7 +1213,6 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3 uint32_t max_sf_size = SRSLTE_SF_LEN(max_fft_sz); sf_buffer[0] = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*max_sf_size); - input_cfo_corrected = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*15*max_sf_size); measure_p.init(sf_buffer, log_h, 1, max_sf_window); @@ -1257,7 +1249,6 @@ void phch_recv::scell_recv::reset() void phch_recv::scell_recv::deinit() { srslte_sync_free(&sync_find); - free(input_cfo_corrected); free(sf_buffer[0]); } @@ -1335,40 +1326,23 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, found_cell.nof_ports = 1; // Use port 0 only for measurement measure_p.set_cell(found_cell); - // Correct CFO - /* - srslte_cfo_correct(&sync_find.cfo_corr_frame, - input_buffer, - input_cfo_corrected, - -srslte_sync_get_cfo(&sync_find)/sync_find.fft_size); - */ - switch(measure_p.run_multiple_subframes(input_buffer, peak_idx, sf_idx, nof_sf)) { case measure::MEASURE_OK: // Consider a cell to be detectable 8.1.2.2.1.1 from 36.133. Currently only using first condition if (measure_p.rsrp() > ABSOLUTE_RSRP_THRESHOLD_DBM) { - // Check the cell id has been correctly identified by using the correlation of the RS sequences - // By experimentation, typically the cross-correlation is ~3/4 dB less - if (measure_p.rsrp_n() > measure_p.rsrp() - 6) { - cells[nof_cells].pci = found_cell.id; - cells[nof_cells].rsrp = measure_p.rsrp(); - cells[nof_cells].rsrq = measure_p.rsrq(); - cells[nof_cells].offset = measure_p.frame_st_idx(); - - Info( - "INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, corr-RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", - nof_cells, cell_id, measure_p.rsrp(), measure_p.rsrp_n(), measure_p.frame_st_idx(), sync_find.peak_value, - sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); - - nof_cells++; - } else { - Info( - "INTRA: Found phantom cell %d: PCI=%03d, RSRP=%5.1f dBm, corr-RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", - nof_cells, cell_id, measure_p.rsrp(), measure_p.rsrp_n(), measure_p.frame_st_idx(), sync_find.peak_value, - sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); - } + cells[nof_cells].pci = found_cell.id; + cells[nof_cells].rsrp = measure_p.rsrp(); + cells[nof_cells].rsrq = measure_p.rsrq(); + cells[nof_cells].offset = measure_p.frame_st_idx(); + + Info( + "INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, nof_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n", + nof_cells, cell_id, measure_p.rsrp(), measure_p.frame_st_idx(), sync_find.peak_value, + sf_idx, nof_sf, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find)); + + nof_cells++; /* if (sic_pss_enabled) { From f9d770e50e4e80cc35bd478cf2b70666645930ce Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 17:30:55 +0100 Subject: [PATCH 50/70] Added option for Doppler frequency correction --- lib/include/srslte/interfaces/ue_interfaces.h | 3 ++- srsue/hdr/phy/phch_recv.h | 2 ++ srsue/hdr/phy/phch_worker.h | 1 - srsue/src/main.cc | 11 ++++----- srsue/src/phy/phch_recv.cc | 23 +++++++++++++++++-- srsue/src/phy/phch_worker.cc | 16 +------------ srsue/ue.conf.example | 3 +++ 7 files changed, 34 insertions(+), 25 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 9a7a68a34..e69419983 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -474,7 +474,8 @@ typedef struct { int cqi_max; int cqi_fixed; float snr_ema_coeff; - std::string snr_estim_alg; + std::string snr_estim_alg; + bool cfo_is_doppler; bool cfo_integer_enabled; float cfo_correct_tol_hz; float cfo_pss_ema; diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index d71bcb1d5..f955b30ce 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -104,6 +104,8 @@ private: void cell_search_inc(); void cell_reselect(); + float get_cfo(); + uint32_t new_earfcn; srslte_cell_t new_cell; diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 6f72285b2..e87603e5d 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -73,7 +73,6 @@ public: float get_rsrp(); float get_noise(); float get_cfo(); - float get_ul_cfo(); private: /* Inherited from thread_pool::worker. Function called every subframe to run the DL/UL processing */ diff --git a/srsue/src/main.cc b/srsue/src/main.cc index d2d029c63..00fd23cf8 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -203,6 +203,11 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.equalizer_mode)->default_value("mmse"), "Equalizer mode") + ("expert.cfo_is_doppler", + bpo::value(&args->expert.phy.cfo_is_doppler)->default_value(false), + "Assume detected CFO is doppler and correct the UL in the same direction. If disabled, the CFO is assumed" + "to be caused by the local oscillator and the UL correction is in the opposite direction. Default assumes oscillator.") + ("expert.cfo_integer_enabled", bpo::value(&args->expert.phy.cfo_integer_enabled)->default_value(false), "Enables integer CFO estimation and correction.") @@ -215,12 +220,6 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.cfo_pss_ema)->default_value(DEFAULT_CFO_EMA_TRACK), "CFO Exponential Moving Average coefficient for PSS estimation during TRACK.") - /* REF EMA is currently not used - ("expert.cfo_ref_ema", - bpo::value(&args->expert.phy.cfo_ref_ema)->default_value(0.01), - "CFO Exponential Moving Average coefficient for RS estimation after PSS acquisition") - */ - ("expert.cfo_ref_mask", bpo::value(&args->expert.phy.cfo_ref_mask)->default_value(1023), "Bitmask for subframes on which to run RS estimation (set to 0 to disable, default all sf)") diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 456f14ea0..38dd5b561 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -428,6 +428,25 @@ bool phch_recv::set_frequency() } } +float phch_recv::get_cfo() +{ + float cfo = srslte_ue_sync_get_cfo(&ue_sync); + + float ret = cfo*ul_dl_factor; + + if (worker_com->args->cfo_is_doppler) { + ret *= -1; + } + + if (radio_h->get_freq_offset() != 0.0f) { + /* Compensates the radio frequency offset applied equally to DL and UL */ + const float offset_hz = (float) radio_h->get_freq_offset() * (1.0f - ul_dl_factor); + ret = cfo - offset_hz; + } + + return ret/15000; +} + void phch_recv::set_sampling_rate() { current_srate = (float) srslte_sampling_freq_hz(cell.nof_prb); @@ -633,7 +652,7 @@ void phch_recv::run_thread() metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync); metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync); - worker->set_cfo(ul_dl_factor * metrics.cfo / 15000); + worker->set_cfo(get_cfo()); worker_com->set_sync_metrics(metrics); /* Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time */ @@ -659,7 +678,7 @@ void phch_recv::run_thread() if (prach_buffer->is_ready_to_send(tti)) { srslte_timestamp_copy(&tx_time_prach, &rx_time); srslte_timestamp_add(&tx_time_prach, 0, prach::tx_advance_sf * 1e-3); - prach_buffer->send(radio_h, ul_dl_factor * metrics.cfo / 15000, worker_com->pathloss, tx_time_prach); + prach_buffer->send(radio_h, get_cfo(), worker_com->pathloss, tx_time_prach); radio_h->tx_end(); worker_com->p0_preamble = prach_buffer->get_p0_preamble(); worker_com->cur_radio_power = SRSLTE_MIN(SRSLTE_PC_MAX, worker_com->pathloss+worker_com->p0_preamble); diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index b3a33ea6c..e613719cb 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -223,20 +223,6 @@ float phch_worker::get_cfo() return cfo; } -float phch_worker::get_ul_cfo() { - srslte::radio *radio = phy->get_radio(); - - if (radio->get_freq_offset() != 0.0f) { - /* Compensates the radio frequency offset applied equally to DL and UL */ - const float ul_dl_ratio = (float) radio->get_tx_freq() / (float) radio->get_rx_freq(); - const float offset_hz = (float) radio->get_freq_offset() * (1.0f - ul_dl_ratio); - return cfo - offset_hz / (15000); - } else { - return cfo; - } - -} - void phch_worker::work_imp() { if (!cell_initiated) { @@ -360,7 +346,7 @@ void phch_worker::work_imp() } /* Set UL CFO before transmission */ - srslte_ue_ul_set_cfo(&ue_ul, get_ul_cfo()); + srslte_ue_ul_set_cfo(&ue_ul, cfo); /* Transmit PUSCH, PUCCH or SRS */ bool signal_ready = false; diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 52442e4af..a3de1a678 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -172,6 +172,8 @@ enable = false # cfo_correct_tol_hz: Tolerance (in Hz) for digial CFO compensation. Lower tolerance means that # a new table will be generated more often. # +# cfo_is_doppler: Assume detected CFO is doppler and correct the UL in the same direction. If disabled, the CFO is assumed +# to be caused by the local oscillator and the UL correction is in the opposite direction. Default assumes oscillator. # cfo_pss_ema: CFO Exponential Moving Average coefficient for PSS estimation during TRACK. # cfo_ref_ema: CFO Exponential Moving Average coefficient for RS estimation after PSS acquisition # cfo_ref_mask: Bitmask for subframes on which to run RS estimation (set to 0 to disable, default sf=[1, 5]) @@ -211,6 +213,7 @@ enable = false #pdsch_csi_enabled = true # Caution! Only TM1 supported! # CFO related values +#cfo_is_doppler = false #cfo_integer_enabled = false #cfo_correct_tol_hz = 1.0 #cfo_pss_ema = 0.05 From 155ac12193e85f245a601837eff9e59134dd48c7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 17:35:11 +0100 Subject: [PATCH 51/70] Remove measObject properly when release (fixes not enough unique timers bug) --- srsue/src/upper/rrc.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 8c346bfaa..c01c2fc37 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2462,7 +2462,10 @@ void rrc::rrc_meas::reset() filter_k_rsrp = liblte_rrc_filter_coefficient_num[LIBLTE_RRC_FILTER_COEFFICIENT_FC4]; filter_k_rsrq = liblte_rrc_filter_coefficient_num[LIBLTE_RRC_FILTER_COEFFICIENT_FC4]; objects.clear(); - active.clear(); + std::map::iterator iter = active.begin(); + while (iter != active.end()) { + remove_meas_id(iter++); + } reports_cfg.clear(); phy->meas_reset(); bzero(&pcell_measurement, sizeof(meas_value_t)); @@ -2983,12 +2986,15 @@ void rrc::rrc_meas::parse_meas_config(LIBLTE_RRC_MEAS_CONFIG_STRUCT *cfg) } else { is_new = true; active[measId->meas_id].periodic_timer = mac_timers->timer_get_unique_id(); + if (!active[measId->meas_id].periodic_timer) { + log_h->error("Could not get unique timer id\n"); + } } active[measId->meas_id].object_id = measId->meas_obj_id; active[measId->meas_id].report_id = measId->rep_cnfg_id; - log_h->info("MEAS: %s measId=%d, measObjectId=%d, reportConfigId=%d, nof_values=%d\n", + log_h->info("MEAS: %s measId=%d, measObjectId=%d, reportConfigId=%d, timer_id=%d, nof_values=%d\n", is_new?"Added":"Updated", measId->meas_id, measId->meas_obj_id, measId->rep_cnfg_id, - active[measId->meas_id].cell_values.size()); + active[measId->meas_id].periodic_timer, active[measId->meas_id].cell_values.size()); } } From 209293104f822910a428c309e47b5827c2baa642 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 18:00:26 +0100 Subject: [PATCH 52/70] Fix bug introduced in 33ebde5387ce652d39bc7506400c05ae129018cc causing the UE to disconnect when reselecting cell --- srsue/src/upper/rrc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index c01c2fc37..63d64808a 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -661,7 +661,7 @@ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { if (!ret) { phy->cell_search_next(); } - } else if (!ho_syncing) { + } else if (state < RRC_STATE_CONNECTING) { state = RRC_STATE_CELL_SELECTING; } From 58f204d94aca8bc2a4c5a6ed2df77466556c5a17 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 21:19:02 +0100 Subject: [PATCH 53/70] Set DEBUG constant for RelWithDebug --- CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10952a010..a91e11da7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,9 +257,14 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -DDEBUG_MODE") else(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") + if(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG_MODE") + else(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") + endif(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") + if (USE_LTE_RATES) message(STATUS "Using standard LTE sampling rates") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFORCE_STANDARD_RATE") From bd258372ea4453080af86ba72741bdde5277bdee Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 23:08:36 +0100 Subject: [PATCH 54/70] Fixes #164 --- lib/src/phy/phch/pbch.c | 61 +++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/lib/src/phy/phch/pbch.c b/lib/src/phy/phch/pbch.c index e7c0c33af..302ee9e7d 100644 --- a/lib/src/phy/phch/pbch.c +++ b/lib/src/phy/phch/pbch.c @@ -399,35 +399,41 @@ uint32_t srslte_pbch_crc_check(srslte_pbch_t *q, uint8_t *bits, uint32_t nof_por int decode_frame(srslte_pbch_t *q, uint32_t src, uint32_t dst, uint32_t n, uint32_t nof_bits, uint32_t nof_ports) { int j; - - memcpy(&q->temp[dst * nof_bits], &q->llr[src * nof_bits], - n * nof_bits * sizeof(float)); - /* descramble */ - srslte_scrambling_f_offset(&q->seq, &q->temp[dst * nof_bits], dst * nof_bits, - n * nof_bits); + if (dst + n <= 4 && src + n <= 4) { + memcpy(&q->temp[dst * nof_bits], &q->llr[src * nof_bits], + n * nof_bits * sizeof(float)); - for (j = 0; j < dst * nof_bits; j++) { - q->temp[j] = SRSLTE_RX_NULL; - } - for (j = (dst + n) * nof_bits; j < 4 * nof_bits; j++) { - q->temp[j] = SRSLTE_RX_NULL; - } + /* descramble */ + srslte_scrambling_f_offset(&q->seq, &q->temp[dst * nof_bits], dst * nof_bits, + n * nof_bits); - /* unrate matching */ - srslte_rm_conv_rx(q->temp, 4 * nof_bits, q->rm_f, SRSLTE_BCH_ENCODED_LEN); - - /* Normalize LLR */ - srslte_vec_sc_prod_fff(q->rm_f, 1.0/((float) 2*n), q->rm_f, SRSLTE_BCH_ENCODED_LEN); - - /* decode */ - srslte_viterbi_decode_f(&q->decoder, q->rm_f, q->data, SRSLTE_BCH_PAYLOADCRC_LEN); + for (j = 0; j < dst * nof_bits; j++) { + q->temp[j] = SRSLTE_RX_NULL; + } + for (j = (dst + n) * nof_bits; j < 4 * nof_bits; j++) { + q->temp[j] = SRSLTE_RX_NULL; + } + + /* unrate matching */ + srslte_rm_conv_rx(q->temp, 4 * nof_bits, q->rm_f, SRSLTE_BCH_ENCODED_LEN); - if (!srslte_pbch_crc_check(q, q->data, nof_ports)) { - return 1; + /* Normalize LLR */ + srslte_vec_sc_prod_fff(q->rm_f, 1.0/((float) 2*n), q->rm_f, SRSLTE_BCH_ENCODED_LEN); + + /* decode */ + srslte_viterbi_decode_f(&q->decoder, q->rm_f, q->data, SRSLTE_BCH_PAYLOADCRC_LEN); + + if (!srslte_pbch_crc_check(q, q->data, nof_ports)) { + return 1; + } else { + return SRSLTE_SUCCESS; + } } else { - return SRSLTE_SUCCESS; + fprintf(stderr, "Error in PBCH decoder: Invalid frame pointers dst=%d, src=%d, n=%d\n", src, dst, n); + return -1; } + } /* Decodes the PBCH channel @@ -514,7 +520,7 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS for (nb = 0; nb < q->frame_idx; nb++) { for (dst = 0; (dst < 4 - nb); dst++) { for (src = 0; src < q->frame_idx - nb; src++) { - ret = decode_frame(q, src, dst, nb + 1, nof_bits, nant); + ret = decode_frame(q, src, dst, nb + 1, nof_bits, nant); if (ret == 1) { if (sfn_offset) { *sfn_offset = (int) dst - src + q->frame_idx - 1; @@ -526,15 +532,16 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS memcpy(bch_payload, q->data, sizeof(uint8_t) * SRSLTE_BCH_PAYLOAD_LEN); } INFO("Decoded PBCH: src=%d, dst=%d, nb=%d, sfn_offset=%d\n", src, dst, nb+1, (int) dst - src + q->frame_idx - 1); - return 1; + srslte_pbch_decode_reset(q); + return 1; } } } } } nant++; - } while(nant <= q->cell.nof_ports); - + } while(nant <= q->cell.nof_ports); + /* If not found, make room for the next packet of radio frame symbols */ if (q->frame_idx == 4) { memmove(q->llr, &q->llr[nof_bits], nof_bits * 3 * sizeof(float)); From c850e2f87adab470c0692e5781b22a0a43d3a92b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 14 Mar 2018 23:08:51 +0100 Subject: [PATCH 55/70] Added check for issue #165 --- lib/src/common/pdu.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/src/common/pdu.cc b/lib/src/common/pdu.cc index 69c19518c..b3928f11b 100644 --- a/lib/src/common/pdu.cc +++ b/lib/src/common/pdu.cc @@ -120,8 +120,14 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h) { int init_rem_len=rem_len; sch_subh padding; - padding.set_padding(); - + padding.set_padding(); + + if (nof_subheaders <= 0) { + log_h->error("Writting PDU: nof_subheaders=%d\n", nof_subheaders); + log_h->console("Writting PDU: nof_subheaders=%d\n", nof_subheaders); + return NULL; + } + if (init_rem_len < 0) { log_h->error("init_rem_len=%d\n", init_rem_len); return NULL; From d66a455479bafe46141e4de4618a0dda65d6c621 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 14 Mar 2018 17:44:51 +0100 Subject: [PATCH 56/70] add check for invalid nof subheaders in MAC PDU --- lib/src/common/pdu.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/src/common/pdu.cc b/lib/src/common/pdu.cc index b3928f11b..b020cde81 100644 --- a/lib/src/common/pdu.cc +++ b/lib/src/common/pdu.cc @@ -132,7 +132,12 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h) log_h->error("init_rem_len=%d\n", init_rem_len); return NULL; } - + + if (nof_subheaders <= 0) { + log_h->error("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); + return NULL; + } + /* If last SDU has zero payload, remove it. FIXME: Why happens this?? */ if (subheaders[nof_subheaders-1].get_payload_size() == 0) { del_subh(); From 25ccd296461ed8ce32044bbda200f8d02e3ff2bd Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 15 Mar 2018 09:59:39 +0100 Subject: [PATCH 57/70] fix issue when cell search doesn't set rx frequency because phy init takes too long See commit f3c04949b755ce135fef9488f213e3d7fed60b88 for reference and a more detailed description. --- srsue/src/phy/phch_recv.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 38dd5b561..4563c1476 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -280,10 +280,8 @@ void phch_recv::cell_search_inc() rrc->earfcn_end(); } else { Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size()); - if (current_earfcn != earfcn[cur_earfcn_index]) { - current_earfcn = earfcn[cur_earfcn_index]; - set_frequency(); - } + current_earfcn = earfcn[cur_earfcn_index]; + set_frequency(); phy_state = CELL_SEARCH; } } From 599cf9bc076ade9012602880df7e24a782beb64d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 10:56:18 +0100 Subject: [PATCH 58/70] Resolved conflicting commits d66a455479bafe46141e4de4618a0dda65d6c621 and c850e2f87adab470c0692e5781b22a0a43d3a92b --- lib/src/common/pdu.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/src/common/pdu.cc b/lib/src/common/pdu.cc index b020cde81..b0cdef638 100644 --- a/lib/src/common/pdu.cc +++ b/lib/src/common/pdu.cc @@ -123,8 +123,8 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h) padding.set_padding(); if (nof_subheaders <= 0) { - log_h->error("Writting PDU: nof_subheaders=%d\n", nof_subheaders); - log_h->console("Writting PDU: nof_subheaders=%d\n", nof_subheaders); + log_h->error("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); + log_h->console("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); return NULL; } @@ -133,11 +133,6 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h) return NULL; } - if (nof_subheaders <= 0) { - log_h->error("Trying to write packet with invalid number of subheaders (nof_subheaders=%d).\n", nof_subheaders); - return NULL; - } - /* If last SDU has zero payload, remove it. FIXME: Why happens this?? */ if (subheaders[nof_subheaders-1].get_payload_size() == 0) { del_subh(); From f470645e9042c07fca26b635b770d82440b79832 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 10:56:46 +0100 Subject: [PATCH 59/70] Fix for real issue #164 --- lib/src/phy/phch/pbch.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/src/phy/phch/pbch.c b/lib/src/phy/phch/pbch.c index 302ee9e7d..722a28b4c 100644 --- a/lib/src/phy/phch/pbch.c +++ b/lib/src/phy/phch/pbch.c @@ -489,6 +489,8 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS q->frame_idx++; ret = 0; + uint32_t frame_idx = q->frame_idx; + /* Try decoding for 1 to cell.nof_ports antennas */ if (q->search_all_ports) { nant = 1; @@ -498,7 +500,7 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS do { if (nant != 3) { - DEBUG("Trying %d TX antennas with %d frames\n", nant, q->frame_idx); + DEBUG("Trying %d TX antennas with %d frames\n", nant, frame_idx); /* in control channels, only diversity is supported */ if (nant == 1) { @@ -511,19 +513,19 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS } /* demodulate symbols */ - srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, &q->llr[nof_bits * (q->frame_idx - 1)], q->nof_symbols); + srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, &q->llr[nof_bits * (frame_idx - 1)], q->nof_symbols); /* We don't know where the 40 ms begin, so we try all combinations. E.g. if we received * 4 frames, try 1,2,3,4 individually, 12, 23, 34 in pairs, 123, 234 and finally 1234. * We know they are ordered. */ - for (nb = 0; nb < q->frame_idx; nb++) { + for (nb = 0; nb < frame_idx; nb++) { for (dst = 0; (dst < 4 - nb); dst++) { - for (src = 0; src < q->frame_idx - nb; src++) { + for (src = 0; src < frame_idx - nb; src++) { ret = decode_frame(q, src, dst, nb + 1, nof_bits, nant); if (ret == 1) { if (sfn_offset) { - *sfn_offset = (int) dst - src + q->frame_idx - 1; + *sfn_offset = (int) dst - src + frame_idx - 1; } if (nof_tx_ports) { *nof_tx_ports = nant; @@ -531,7 +533,7 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS if (bch_payload) { memcpy(bch_payload, q->data, sizeof(uint8_t) * SRSLTE_BCH_PAYLOAD_LEN); } - INFO("Decoded PBCH: src=%d, dst=%d, nb=%d, sfn_offset=%d\n", src, dst, nb+1, (int) dst - src + q->frame_idx - 1); + INFO("Decoded PBCH: src=%d, dst=%d, nb=%d, sfn_offset=%d\n", src, dst, nb+1, (int) dst - src + frame_idx - 1); srslte_pbch_decode_reset(q); return 1; } From d873eaca5c0dd96827240bf7ab356df4d6d09b62 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 11:14:22 +0100 Subject: [PATCH 60/70] Assign same timer id after release (was not really a bug) --- lib/include/srslte/common/timers.h | 14 +++++++------- srsue/src/upper/rrc.cc | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/include/srslte/common/timers.h b/lib/include/srslte/common/timers.h index d77692d5a..7517aa751 100644 --- a/lib/include/srslte/common/timers.h +++ b/lib/include/srslte/common/timers.h @@ -151,15 +151,15 @@ public: fprintf(stderr, "Error getting unique timer id: no more timers available\n"); return 0; } else { - while(used_timers[next_timer]) { - next_timer++; - if (next_timer >= nof_timers) { - next_timer=0; + for (uint32_t i=0;itimer_get(active[measId].periodic_timer)->stop(); mac_timers->timer_release_id(active[measId].periodic_timer); - log_h->info("MEAS: Removed measId=%d\n", measId); + log_h->info("MEAS: Removed measId=%d, timer_id=%d\n", measId, active[measId].periodic_timer); active.erase(measId); } else { log_h->warning("MEAS: Removing unexistent measId=%d\n", measId); @@ -2846,7 +2846,7 @@ void rrc::rrc_meas::remove_meas_id(uint32_t measId) { void rrc::rrc_meas::remove_meas_id(std::map::iterator it) { mac_timers->timer_get(it->second.periodic_timer)->stop(); mac_timers->timer_release_id(it->second.periodic_timer); - log_h->info("MEAS: Removed measId=%d\n", it->first); + log_h->info("MEAS: Removed measId=%d, timer_id=%d\n", it->first, active[measId].periodic_timer); active.erase(it); } From 5342bb430e6016997dce5c97e4aced28e4adc175 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 11:15:33 +0100 Subject: [PATCH 61/70] previous commit not compiling --- srsue/src/upper/rrc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 6f2ede299..6c8ab63cc 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2846,7 +2846,7 @@ void rrc::rrc_meas::remove_meas_id(uint32_t measId) { void rrc::rrc_meas::remove_meas_id(std::map::iterator it) { mac_timers->timer_get(it->second.periodic_timer)->stop(); mac_timers->timer_release_id(it->second.periodic_timer); - log_h->info("MEAS: Removed measId=%d, timer_id=%d\n", it->first, active[measId].periodic_timer); + log_h->info("MEAS: Removed measId=%d, timer_id=%d\n", it->first, it->second.periodic_timer); active.erase(it); } From 64cc34adb07477af00bfd369e41f13af6ea9cf18 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 11:31:09 +0100 Subject: [PATCH 62/70] previous commit not working --- lib/include/srslte/common/timers.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/include/srslte/common/timers.h b/lib/include/srslte/common/timers.h index 7517aa751..5e8b1cfd5 100644 --- a/lib/include/srslte/common/timers.h +++ b/lib/include/srslte/common/timers.h @@ -153,6 +153,7 @@ public: } else { for (uint32_t i=0;i Date: Thu, 15 Mar 2018 11:31:37 +0100 Subject: [PATCH 63/70] Revert "fix issue when cell search doesn't set rx frequency because phy init takes too long" This reverts commit 25ccd296461ed8ce32044bbda200f8d02e3ff2bd. --- srsue/src/phy/phch_recv.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 4563c1476..38dd5b561 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -280,8 +280,10 @@ void phch_recv::cell_search_inc() rrc->earfcn_end(); } else { Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size()); - current_earfcn = earfcn[cur_earfcn_index]; - set_frequency(); + if (current_earfcn != earfcn[cur_earfcn_index]) { + current_earfcn = earfcn[cur_earfcn_index]; + set_frequency(); + } phy_state = CELL_SEARCH; } } From df0dcb27e70a6867ac50aa179eb47a77eb8125f5 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 11:31:39 +0100 Subject: [PATCH 64/70] Revert "PHCH Receive is reset, the current EARFCN becomes the first one in the list." This reverts commit f3c04949b755ce135fef9488f213e3d7fed60b88. --- srsue/src/phy/phch_recv.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 38dd5b561..5821a1bf3 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -132,11 +132,7 @@ void phch_recv::reset() next_offset = 0; cell_is_set = false; srate_mode = SRATE_NONE; - if (!earfcn.empty()) { - current_earfcn = earfcn[0]; - } else { - current_earfcn = 0; - } + current_earfcn = 0; sfn_p.reset(); measure_p.reset(); search_p.reset(); From e845339d5406cc54e9b35fe343150e71078dcd00 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 11:41:49 +0100 Subject: [PATCH 65/70] rrc.connected() return true during HO --- srsue/src/ue.cc | 2 +- srsue/src/upper/rrc.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 1d83f087e..ca8c9002b 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -275,7 +275,7 @@ void ue::stop() bool ue::is_attached() { - return (RRC_STATE_CONNECTED == rrc.get_state()); + return rrc.is_connected(); } void ue::start_plot() { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 6c8ab63cc..83d7174ca 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -156,7 +156,7 @@ rrc_state_t rrc::get_state() { } bool rrc::is_connected() { - return (RRC_STATE_CONNECTED == state); + return (RRC_STATE_CONNECTED >= state && state < RRC_STATE_LEAVE_CONNECTED); } bool rrc::have_drb() { From 86d4ce52e05255c64246f75317fe391aa0c80e8a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 12:27:55 +0100 Subject: [PATCH 66/70] Make intra-frequency measurement period/length a parameter --- lib/include/srslte/interfaces/ue_interfaces.h | 2 ++ srsue/hdr/phy/phch_recv.h | 2 -- srsue/src/main.cc | 8 ++++++++ srsue/src/phy/phch_recv.cc | 14 +++++++------- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index e69419983..bea0cb05c 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -494,6 +494,8 @@ typedef struct { bool sic_pss_enabled; float rx_gain_offset; bool pdsch_csi_enabled; + uint32_t intra_freq_meas_len_ms; + uint32_t intra_freq_meas_period_ms; } phy_args_t; diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index f955b30ce..378dfb8f9 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -233,8 +233,6 @@ private: void write(uint32_t tti, cf_t *data, uint32_t nsamples); private: void run_thread(); - const static int INTRA_FREQ_MEAS_LEN_MS = 20; - const static int INTRA_FREQ_MEAS_PERIOD_MS = 200; const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5; scell_recv scell; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 00fd23cf8..8753e7630 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -203,6 +203,14 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.equalizer_mode)->default_value("mmse"), "Equalizer mode") + ("expert.intra_freq_meas_len_ms", + bpo::value(&args->expert.phy.intra_freq_meas_len_ms)->default_value(20), + "Duration of the intra-frequency neighbour cell measurement in ms.") + + ("expert.intra_freq_meas_period_ms", + bpo::value(&args->expert.phy.intra_freq_meas_period_ms)->default_value(200), + "Period of intra-frequency neighbour cell measurement in ms. Maximum as per 3GPP is 200 ms.") + ("expert.cfo_is_doppler", bpo::value(&args->expert.phy.cfo_is_doppler)->default_value(false), "Assume detected CFO is doppler and correct the UL in the same direction. If disabled, the CFO is assumed" diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 5821a1bf3..8227a2882 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1436,11 +1436,11 @@ void phch_recv::intra_measure::init(phch_common *common, rrc_interface_phy *rrc, receive_enabled = false; // Start scell - scell.init(log_h, common->args->sic_pss_enabled, INTRA_FREQ_MEAS_LEN_MS); + scell.init(log_h, common->args->sic_pss_enabled, common->args->intra_freq_meas_len_ms); - search_buffer = (cf_t*) srslte_vec_malloc(INTRA_FREQ_MEAS_LEN_MS*SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB)*sizeof(cf_t)); + search_buffer = (cf_t*) srslte_vec_malloc(common->args->intra_freq_meas_len_ms*SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB)*sizeof(cf_t)); - if (srslte_ringbuffer_init(&ring_buffer, sizeof(cf_t)*INTRA_FREQ_MEAS_LEN_MS*2*SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB))) { + if (srslte_ringbuffer_init(&ring_buffer, sizeof(cf_t)*common->args->intra_freq_meas_len_ms*2*SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB))) { return; } @@ -1510,7 +1510,7 @@ void phch_recv::intra_measure::rem_cell(int pci) { void phch_recv::intra_measure::write(uint32_t tti, cf_t *data, uint32_t nsamples) { if (receive_enabled) { - if ((tti%INTRA_FREQ_MEAS_PERIOD_MS) == 0) { + if ((tti%common->args->intra_freq_meas_period_ms) == 0) { receiving = true; receive_cnt = 0; measure_tti = tti; @@ -1522,7 +1522,7 @@ void phch_recv::intra_measure::write(uint32_t tti, cf_t *data, uint32_t nsamples receiving = false; } else { receive_cnt++; - if (receive_cnt == INTRA_FREQ_MEAS_LEN_MS) { + if (receive_cnt == common->args->intra_freq_meas_len_ms) { tti_sync.increase(); receiving = false; } @@ -1541,8 +1541,8 @@ void phch_recv::intra_measure::run_thread() if (running) { // Read data from buffer and find cells in it - srslte_ringbuffer_read(&ring_buffer, search_buffer, INTRA_FREQ_MEAS_LEN_MS*current_sflen*sizeof(cf_t)); - int found_cells = scell.find_cells(search_buffer, common->rx_gain_offset, primary_cell, INTRA_FREQ_MEAS_LEN_MS, info); + srslte_ringbuffer_read(&ring_buffer, search_buffer, common->args->intra_freq_meas_len_ms*current_sflen*sizeof(cf_t)); + int found_cells = scell.find_cells(search_buffer, common->rx_gain_offset, primary_cell, common->args->intra_freq_meas_len_ms, info); receiving = false; for (int i=0;i Date: Thu, 15 Mar 2018 18:35:40 +0100 Subject: [PATCH 67/70] Fixed bug in compute_ri() when passed NULL parameter causing segfault in MIMO --- srsue/src/phy/phch_worker.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index e613719cb..cb27a5000 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -418,7 +418,9 @@ void phch_worker::compute_ri(uint8_t *ri, uint8_t *pmi, float *sinr) { /* If 2 ort more receiving antennas, select RI */ float cn = 0.0f; srslte_ue_dl_ri_select(&ue_dl, ri, &cn); - Debug("TM3 RI select %d layers, κ=%fdB\n", (*ri) + 1, cn); + if (ri) { + Debug("TM3 RI select %d layers, κ=%fdB\n", (*ri) + 1, cn); + } } else { /* If only one receiving antenna, force RI for 1 layer */ if (ri) { From 622b3221d73dbf9ef067eb196d924e8caacbe67e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 15 Mar 2018 18:37:16 +0100 Subject: [PATCH 68/70] Don't restart RX stream when setting RX srate (causes UHD corruption in MIMO) --- lib/src/radio/radio.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index fc21b73be..7008790a3 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -301,9 +301,7 @@ void radio::set_master_clock_rate(double rate) void radio::set_rx_srate(double srate) { - srslte_rf_stop_rx_stream(&rf_device); srslte_rf_set_rx_srate(&rf_device, srate); - srslte_rf_start_rx_stream(&rf_device, false); } void radio::set_tx_freq(double freq) From 548a4ae29d02cfad20f6f14b14bae045a9ad91a7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Mar 2018 11:22:40 +0100 Subject: [PATCH 69/70] RRC is_connected return and srsgui crashing if ports=0 when init --- srsue/hdr/phy/phch_worker.h | 12 ++++++++++-- srsue/src/upper/rrc.cc | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index e87603e5d..28c4715ad 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -63,8 +63,16 @@ public: void write_trace(std::string filename); int read_ce_abs(float *ce_abs, uint32_t tx_antenna, uint32_t rx_antenna); - uint32_t get_cell_nof_ports() {return cell.nof_ports;}; - uint32_t get_rx_nof_antennas() {return ue_dl.nof_rx_antennas;}; + uint32_t get_cell_nof_ports() { + if (cell_initiated) { + return cell.nof_ports; + } else { + return 1; + } + }; + uint32_t get_rx_nof_antennas() { + return ue_dl.nof_rx_antennas; + }; int read_pdsch_d(cf_t *pdsch_d); void start_plot(); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 83d7174ca..e419ea710 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -156,7 +156,7 @@ rrc_state_t rrc::get_state() { } bool rrc::is_connected() { - return (RRC_STATE_CONNECTED >= state && state < RRC_STATE_LEAVE_CONNECTED); + return (state >= RRC_STATE_CONNECTED && state < RRC_STATE_LEAVE_CONNECTED); } bool rrc::have_drb() { From 321a750f561d276d0bbe8a4b066ff239a735f7be Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 16 Mar 2018 11:23:10 +0100 Subject: [PATCH 70/70] Added features to ringbuffer --- lib/include/srslte/phy/utils/ringbuffer.h | 2 ++ lib/src/phy/utils/ringbuffer.c | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/include/srslte/phy/utils/ringbuffer.h b/lib/include/srslte/phy/utils/ringbuffer.h index b8d0cd5c9..a93ebf181 100644 --- a/lib/include/srslte/phy/utils/ringbuffer.h +++ b/lib/include/srslte/phy/utils/ringbuffer.h @@ -28,6 +28,8 @@ SRSLTE_API void srslte_ringbuffer_reset(srslte_ringbuffer_t *q); SRSLTE_API int srslte_ringbuffer_status(srslte_ringbuffer_t *q); +SRSLTE_API int srslte_ringbuffer_space(srslte_ringbuffer_t *q); + SRSLTE_API int srslte_ringbuffer_write(srslte_ringbuffer_t *q, void *ptr, int nof_bytes); diff --git a/lib/src/phy/utils/ringbuffer.c b/lib/src/phy/utils/ringbuffer.c index 8f0c3edf2..02b98a4d8 100644 --- a/lib/src/phy/utils/ringbuffer.c +++ b/lib/src/phy/utils/ringbuffer.c @@ -13,11 +13,10 @@ int srslte_ringbuffer_init(srslte_ringbuffer_t *q, int capacity) } q->active = true; q->capacity = capacity; - srslte_ringbuffer_reset(q); - pthread_mutex_init(&q->mutex, NULL); pthread_cond_init(&q->cvar, NULL); - + srslte_ringbuffer_reset(q); + return 0; } @@ -48,6 +47,11 @@ int srslte_ringbuffer_status(srslte_ringbuffer_t *q) return q->count; } +int srslte_ringbuffer_space(srslte_ringbuffer_t *q) +{ + return q->capacity - q->count; +} + int srslte_ringbuffer_write(srslte_ringbuffer_t *q, void *p, int nof_bytes) { uint8_t *ptr = (uint8_t*) p;