diff --git a/CMakeLists.txt b/CMakeLists.txt index ccc1ce54d..1d0f05568 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -306,8 +306,8 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") endif (HAVE_FMA) if (HAVE_AVX512) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx512f -mavx512cd -DLV_HAVE_AVX512") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx512f -mavx512cd -DLV_HAVE_AVX512") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx512f -mavx512cd -mavx512bw -mavx512dq -DLV_HAVE_AVX512") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx512f -mavx512cd -mavx512bw -mavx512dq -DLV_HAVE_AVX512") endif(HAVE_AVX512) if(NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug") diff --git a/cmake/modules/FindSSE.cmake b/cmake/modules/FindSSE.cmake index e5101deff..24fc23662 100644 --- a/cmake/modules/FindSSE.cmake +++ b/cmake/modules/FindSSE.cmake @@ -142,7 +142,7 @@ if (ENABLE_SSE) # Check compiler for AVX intrinsics # if (CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) - set(CMAKE_REQUIRED_FLAGS "-mavx512f") + set(CMAKE_REQUIRED_FLAGS "-mavx512f -mavx512cd -mavx512bw -mavx512dq -DLV_HAVE_AVX512") check_c_source_runs(" #include int main() diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index 882273ac2..2ee5f5b40 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -728,7 +728,7 @@ int main(int argc, char **argv) { uint8_t mch_table[10]; bzero(&mch_table[0], sizeof(uint8_t)*10); - if(mbsfn_area_id < -1) { + if(mbsfn_area_id > -1) { generate_mcch_table(mch_table, mbsfn_sf_mask); } N_id_2 = cell.id % 3; diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 91c1bddfe..d9ee074cc 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -380,7 +380,7 @@ int main(int argc, char **argv) { } uint8_t mch_table[10]; bzero(&mch_table[0], sizeof(uint8_t)*10); - if(prog_args.mbsfn_area_id < -1) { + if(prog_args.mbsfn_area_id > -1) { generate_mcch_table(mch_table, prog_args.mbsfn_sf_mask); } if(prog_args.cpu_affinity > -1) { diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 60faea607..3c8cfa886 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -138,7 +138,7 @@ public: virtual void paging(LIBLTE_RRC_S_TMSI_STRUCT *ue_identiy) = 0; virtual bool is_attached() = 0; virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; - virtual uint32_t get_ul_count() = 0; + virtual uint32_t get_k_enb_count() = 0; virtual bool get_k_asme(uint8_t *k_asme_, uint32_t n) = 0; virtual uint32_t get_ipv4_addr() = 0; virtual bool get_ipv6_addr(uint8_t *ipv6_addr) = 0; diff --git a/lib/include/srslte/phy/utils/simd.h b/lib/include/srslte/phy/utils/simd.h index 491c1f661..2c5d1ea4b 100644 --- a/lib/include/srslte/phy/utils/simd.h +++ b/lib/include/srslte/phy/utils/simd.h @@ -1341,7 +1341,13 @@ static inline simd_s_t srslte_simd_s_mul(simd_s_t a, simd_s_t b) { static inline simd_s_t srslte_simd_s_neg(simd_s_t a, simd_s_t b) { #ifdef LV_HAVE_AVX512 -#error sign instruction not available in avx512 + __m256i a0 = _mm512_extracti64x4_epi64(a, 0); + __m256i a1 = _mm512_extracti64x4_epi64(a, 1); + __m256i b0 = _mm512_extracti64x4_epi64(b, 0); + __m256i b1 = _mm512_extracti64x4_epi64(b, 1); + __m256i r0 = _mm256_sign_epi16(a0, b0); + __m256i r1 = _mm256_sign_epi16(a1, b1); + return _mm512_inserti64x4(_mm512_broadcast_i64x4(r0), r1, 1); #else /* LV_HAVE_AVX512 */ #ifdef LV_HAVE_AVX2 return _mm256_sign_epi16(a, b); @@ -1350,7 +1356,9 @@ static inline simd_s_t srslte_simd_s_neg(simd_s_t a, simd_s_t b) { return _mm_sign_epi16(a, b); #else /* LV_HAVE_SSE */ #ifdef HAVE_NEON - #error sign instruction not available in Neon + simd_s_t res; + return res; + //#error sign instruction not available in Neon #endif /* HAVE_NEON */ #endif /* LV_HAVE_SSE */ #endif /* LV_HAVE_AVX2 */ @@ -1794,7 +1802,7 @@ static inline simd_b_t srslte_simd_b_xor(simd_b_t a, simd_b_t b) { #endif /* LV_HAVE_AVX512 */ } -static inline simd_s_t srslte_simd_b_sub(simd_s_t a, simd_s_t b) { +static inline simd_b_t srslte_simd_b_sub(simd_b_t a, simd_b_t b) { #ifdef LV_HAVE_AVX512 return _mm512_subs_epi8(a, b); #else /* LV_HAVE_AVX512 */ @@ -1805,7 +1813,7 @@ static inline simd_s_t srslte_simd_b_sub(simd_s_t a, simd_s_t b) { return _mm_subs_epi8(a, b); #else /* LV_HAVE_SSE */ #ifdef HAVE_NEON - return vsubqs_s8(a, b); + return vqsubq_s8(a, b); #endif /* HAVE_NEON */ #endif /* LV_HAVE_SSE */ #endif /* LV_HAVE_AVX2 */ @@ -1814,7 +1822,13 @@ static inline simd_s_t srslte_simd_b_sub(simd_s_t a, simd_s_t b) { static inline simd_s_t srslte_simd_b_neg(simd_b_t a, simd_b_t b) { #ifdef LV_HAVE_AVX512 -#error sign instruction not available in avx512 + __m256i a0 = _mm512_extracti64x4_epi64(a, 0); + __m256i a1 = _mm512_extracti64x4_epi64(a, 1); + __m256i b0 = _mm512_extracti64x4_epi64(b, 0); + __m256i b1 = _mm512_extracti64x4_epi64(b, 1); + __m256i r0 = _mm256_sign_epi8(a0, b0); + __m256i r1 = _mm256_sign_epi8(a1, b1); + return _mm512_inserti64x4(_mm512_broadcast_i64x4(r0), r1, 1); #else /* LV_HAVE_AVX512 */ #ifdef LV_HAVE_AVX2 return _mm256_sign_epi8(a, b); @@ -1823,7 +1837,9 @@ static inline simd_s_t srslte_simd_b_neg(simd_b_t a, simd_b_t b) { return _mm_sign_epi8(a, b); #else /* LV_HAVE_SSE */ #ifdef HAVE_NEON - #error sign instruction not available in Neon + simd_s_t res; + return res; + //#error sign instruction not available in Neon #endif /* HAVE_NEON */ #endif /* LV_HAVE_SSE */ #endif /* LV_HAVE_AVX2 */ diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 59f54e87e..b7324a137 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -257,6 +257,10 @@ int srslte_chest_dl_set_cell(srslte_chest_dl_t *q, srslte_cell_t cell) fprintf(stderr, "Error initializing interpolator\n"); return SRSLTE_ERROR; } + if (srslte_interp_linear_resize(&q->srslte_interp_lin_mbsfn, 6*q->cell.nof_prb, SRSLTE_NRE/6)) { + fprintf(stderr, "Error initializing interpolator\n"); + return SRSLTE_ERROR; + } } ret = SRSLTE_SUCCESS; @@ -387,6 +391,7 @@ static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t srslte_interp_linear_offset(&q->srslte_interp_lin_mbsfn, &pilot_estimates[(2*q->cell.nof_prb) + 6*q->cell.nof_prb*(l - 1)], &ce[srslte_refsignal_mbsfn_nsymbol(l - 1) * q->cell.nof_prb * SRSLTE_NRE], fidx_offset, SRSLTE_NRE/6-fidx_offset); + } } else { if (q->average_subframe) { diff --git a/lib/src/phy/fec/turbodecoder.c b/lib/src/phy/fec/turbodecoder.c index a97180745..0ae094ecf 100644 --- a/lib/src/phy/fec/turbodecoder.c +++ b/lib/src/phy/fec/turbodecoder.c @@ -46,6 +46,7 @@ srslte_tdec_16bit_impl_t gen_impl = { }; /* SSE no-window implementation */ +#ifdef LV_HAVE_SSE #include "srslte/phy/fec/turbodecoder_sse.h" srslte_tdec_16bit_impl_t sse_impl = { tdec_sse_init, @@ -56,7 +57,7 @@ srslte_tdec_16bit_impl_t sse_impl = { }; /* SSE window implementation */ -#ifdef LV_HAVE_SSE + #define WINIMP_IS_SSE16 #include "srslte/phy/fec/turbodecoder_win.h" #undef WINIMP_IS_SSE16 @@ -162,6 +163,7 @@ int srslte_tdec_init_manual(srslte_tdec_t * h, uint32_t max_long_cb, srslte_tdec switch(dec_type) { case SRSLTE_TDEC_AUTO: break; +#ifdef LV_HAVE_SSE case SRSLTE_TDEC_SSE: h->dec16[0] = &sse_impl; h->current_llr_type = SRSLTE_TDEC_16; @@ -170,14 +172,15 @@ int srslte_tdec_init_manual(srslte_tdec_t * h, uint32_t max_long_cb, srslte_tdec h->dec16[0] = &sse16_win_impl; h->current_llr_type = SRSLTE_TDEC_16; break; - case SRSLTE_TDEC_GENERIC: - h->dec16[0] = &gen_impl; - h->current_llr_type = SRSLTE_TDEC_16; - break; case SRSLTE_TDEC_SSE8_WINDOW: h->dec8[0] = &sse8_win_impl; h->current_llr_type = SRSLTE_TDEC_8; break; +#endif + case SRSLTE_TDEC_GENERIC: + h->dec16[0] = &gen_impl; + h->current_llr_type = SRSLTE_TDEC_16; + break; #ifdef LV_HAVE_AVX2 case SRSLTE_TDEC_AVX_WINDOW: h->dec16[0] = &avx16_win_impl; @@ -237,6 +240,11 @@ int srslte_tdec_init_manual(srslte_tdec_t * h, uint32_t max_long_cb, srslte_tdec } if (dec_type == SRSLTE_TDEC_AUTO) { +#ifdef HAVE_NEON + h->dec16[0] = &gen_impl; + h->current_llr_type = SRSLTE_TDEC_16; + //h->dec8[0] = &gen_impl; +#else h->dec16[AUTO_16_SSE] = &sse_impl; h->dec16[AUTO_16_SSEWIN] = &sse16_win_impl; h->dec8[AUTO_8_SSEWIN] = &sse8_win_impl; @@ -244,7 +252,7 @@ int srslte_tdec_init_manual(srslte_tdec_t * h, uint32_t max_long_cb, srslte_tdec h->dec16[AUTO_16_AVXWIN] = &avx16_win_impl; h->dec8[AUTO_8_AVXWIN] = &avx8_win_impl; #endif - +#endif /* HAVE_NEON */ for (int td=0;tddec16[td]) { if ((h->nof_blocks16[td] = h->dec16[td]->tdec_init(&h->dec16_hdlr[td], h->max_long_cb))<0) { diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index f9ea054a0..49df30898 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -612,6 +612,7 @@ static void ulsch_interleave_qm4(uint8_t *g_bits, uint32_t rows, uint32_t cols, int32_t i = 0; #ifndef LV_HAVE_SSE + #ifndef HAVE_NEON __m128i _counter = _mm_slli_epi32(_mm_add_epi32(_mm_mullo_epi32(_counter0,_rows),_mm_set1_epi32(j)), 2); uint8_t *_g_bits = &g_bits[bit_read_idx/8]; @@ -650,6 +651,7 @@ static void ulsch_interleave_qm4(uint8_t *g_bits, uint32_t rows, uint32_t cols, } } bit_read_idx += i * 4; + #endif /* HAVE_NEON */ #endif /* LV_HAVE_SSE */ /* Spare bits */ diff --git a/lib/src/phy/rf/CMakeLists.txt b/lib/src/phy/rf/CMakeLists.txt index 6cec5a6df..700686417 100644 --- a/lib/src/phy/rf/CMakeLists.txt +++ b/lib/src/phy/rf/CMakeLists.txt @@ -19,7 +19,6 @@ # if(RF_FOUND) - # This library is only used by the examples add_library(srslte_rf_utils STATIC rf_utils.c) target_link_libraries(srslte_rf_utils srslte_phy) @@ -38,11 +37,10 @@ if(RF_FOUND) list(APPEND SOURCES_RF rf_blade_imp.c) endif (BLADERF_FOUND) - if (SOAPYSDR_FOUND) + if (SOAPYSDR_FOUND AND ENABLE_SOAPYSDR) add_definitions(-DENABLE_SOAPYSDR) list(APPEND SOURCES_RF rf_soapy_imp.c) - endif (SOAPYSDR_FOUND) - + endif (SOAPYSDR_FOUND AND ENABLE_SOAPYSDR) add_library(srslte_rf SHARED ${SOURCES_RF}) target_link_libraries(srslte_rf srslte_rf_utils srslte_phy) @@ -55,10 +53,9 @@ if(RF_FOUND) target_link_libraries(srslte_rf ${BLADERF_LIBRARIES}) endif (BLADERF_FOUND) - if (SOAPYSDR_FOUND) + if (SOAPYSDR_FOUND AND ENABLE_SOAPYSDR) target_link_libraries(srslte_rf ${SOAPYSDR_LIBRARIES}) - endif (SOAPYSDR_FOUND) - + endif (SOAPYSDR_FOUND AND ENABLE_SOAPYSDR) INSTALL(TARGETS srslte_rf DESTINATION ${LIBRARY_DIR}) endif(RF_FOUND) diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 8571825bf..8e9353236 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -674,7 +674,7 @@ int srslte_ue_dl_decode_mbsfn(srslte_ue_dl_t * q, if (ret == SRSLTE_SUCCESS) { return q->pmch_cfg.grant.mcs[0].tbs; } else { - return 0; + return ret; } } diff --git a/lib/src/phy/utils/test/vector_test.c b/lib/src/phy/utils/test/vector_test.c index 44f8af1ca..03e33305b 100644 --- a/lib/src/phy/utils/test/vector_test.c +++ b/lib/src/phy/utils/test/vector_test.c @@ -226,6 +226,29 @@ TEST(srslte_vec_prod_sss, free(z); ) +TEST(srslte_vec_neg_sss, + MALLOC(int16_t, x); + MALLOC(int16_t, y); + MALLOC(int16_t, z); + + int16_t gold = 0.0f; + for (int i = 0; i < block_size; i++) { + x[i] = RANDOM_S(); + do { y[i] = RANDOM_S(); } while (!y[i]); + } + + TEST_CALL(srslte_vec_neg_sss(x, y, z, block_size)) + + for (int i = 0; i < block_size; i++) { + gold = y[i] < 0 ? -x[i] : x[i]; + mse += abs(gold - z[i]); + } + + free(x); + free(y); + free(z); +) + TEST(srslte_vec_acc_cc, MALLOC(cf_t, x); cf_t z; @@ -868,6 +891,9 @@ int main(int argc, char **argv) { passed[func_count][size_count] = test_srslte_vec_prod_sss(func_names[func_count], &timmings[func_count][size_count], block_size); func_count++; + passed[func_count][size_count] = test_srslte_vec_neg_sss(func_names[func_count], &timmings[func_count][size_count], block_size); + func_count++; + passed[func_count][size_count] = test_srslte_vec_acc_cc(func_names[func_count], &timmings[func_count][size_count], block_size); func_count++; diff --git a/lib/src/phy/utils/vector_simd.c b/lib/src/phy/utils/vector_simd.c index 83f9ea408..1143219b6 100644 --- a/lib/src/phy/utils/vector_simd.c +++ b/lib/src/phy/utils/vector_simd.c @@ -54,7 +54,7 @@ void srslte_vec_xor_bbb_simd(const int8_t *x, const int8_t *y, int8_t *z, const simd_b_t a = srslte_simd_b_loadu(&x[i]); simd_b_t b = srslte_simd_b_loadu(&y[i]); - simd_s_t r = srslte_simd_b_xor(a, b); + simd_b_t r = srslte_simd_b_xor(a, b); srslte_simd_b_storeu(&z[i], r); } @@ -167,19 +167,19 @@ void srslte_vec_sub_bbb_simd(const int8_t *x, const int8_t *y, int8_t *z, const #if SRSLTE_SIMD_B_SIZE if (SRSLTE_IS_ALIGNED(x) && SRSLTE_IS_ALIGNED(y) && SRSLTE_IS_ALIGNED(z)) { for (; i < len - SRSLTE_SIMD_B_SIZE + 1; i += SRSLTE_SIMD_B_SIZE) { - simd_s_t a = srslte_simd_b_load(&x[i]); - simd_s_t b = srslte_simd_b_load(&y[i]); + simd_b_t a = srslte_simd_b_load(&x[i]); + simd_b_t b = srslte_simd_b_load(&y[i]); - simd_s_t r = srslte_simd_b_sub(a, b); + simd_b_t r = srslte_simd_b_sub(a, b); srslte_simd_b_store(&z[i], r); } } else { for (; i < len - SRSLTE_SIMD_S_SIZE + 1; i += SRSLTE_SIMD_S_SIZE) { - simd_s_t a = srslte_simd_b_loadu(&x[i]); - simd_s_t b = srslte_simd_b_loadu(&y[i]); + simd_b_t a = srslte_simd_b_loadu(&x[i]); + simd_b_t b = srslte_simd_b_loadu(&y[i]); - simd_s_t r = srslte_simd_b_sub(a, b); + simd_b_t r = srslte_simd_b_sub(a, b); srslte_simd_b_storeu(&z[i], r); } @@ -222,6 +222,8 @@ void srslte_vec_prod_sss_simd(const int16_t *x, const int16_t *y, int16_t *z, co void srslte_vec_neg_sss_simd(const int16_t *x, const int16_t *y, int16_t *z, const int len) { int i = 0; + +#ifndef HAVE_NEON #if SRSLTE_SIMD_S_SIZE if (SRSLTE_IS_ALIGNED(x) && SRSLTE_IS_ALIGNED(y) && SRSLTE_IS_ALIGNED(z)) { for (; i < len - SRSLTE_SIMD_S_SIZE + 1; i += SRSLTE_SIMD_S_SIZE) { @@ -243,6 +245,7 @@ void srslte_vec_neg_sss_simd(const int16_t *x, const int16_t *y, int16_t *z, con } } #endif /* SRSLTE_SIMD_S_SIZE */ +#endif /* NOT HAVE_NEON*/ for(; i < len; i++){ z[i] = y[i]<0?-x[i]:x[i]; @@ -251,6 +254,8 @@ void srslte_vec_neg_sss_simd(const int16_t *x, const int16_t *y, int16_t *z, con void srslte_vec_neg_bbb_simd(const int8_t *x, const int8_t *y, int8_t *z, const int len) { int i = 0; + +#ifndef HAVE_NEON #if SRSLTE_SIMD_B_SIZE if (SRSLTE_IS_ALIGNED(x) && SRSLTE_IS_ALIGNED(y) && SRSLTE_IS_ALIGNED(z)) { for (; i < len - SRSLTE_SIMD_B_SIZE + 1; i += SRSLTE_SIMD_B_SIZE) { @@ -272,7 +277,7 @@ void srslte_vec_neg_bbb_simd(const int8_t *x, const int8_t *y, int8_t *z, const } } #endif /* SRSLTE_SIMD_S_SIZE */ - +#endif /* NOT HAVE_NEON*/ for(; i < len; i++){ z[i] = y[i]<0?-x[i]:x[i]; } diff --git a/lib/src/upper/pdcp_entity.cc b/lib/src/upper/pdcp_entity.cc index c26c6b9f0..0e0877414 100644 --- a/lib/src/upper/pdcp_entity.cc +++ b/lib/src/upper/pdcp_entity.cc @@ -237,8 +237,6 @@ void pdcp_entity::integrity_generate( uint8_t *msg, uint32_t msg_len, uint8_t *mac) { - uint8_t bearer; - switch(integ_algo) { case INTEGRITY_ALGORITHM_ID_EIA0: @@ -264,6 +262,14 @@ void pdcp_entity::integrity_generate( uint8_t *msg, default: break; } + + log->debug("Integrity gen input:\n"); + log->debug_hex(&k_int[16], 16, " K_int"); + log->debug(" Local count: %d\n", tx_count); + log->debug(" Bearer ID: %d\n", get_bearer_id(lcid)); + log->debug(" Direction: %s\n", (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? "Downlink" : "Uplink"); + log->debug_hex(msg, msg_len, " Message"); + log->debug_hex(mac, 4, "MAC (generated)"); } bool pdcp_entity::integrity_verify(uint8_t *msg, @@ -301,6 +307,13 @@ bool pdcp_entity::integrity_verify(uint8_t *msg, break; } + log->debug("Integrity check input:\n"); + log->debug_hex(&k_int[16], 16, " K_int"); + log->debug(" Local count: %d\n", count); + log->debug(" Bearer ID: %d\n", get_bearer_id(lcid)); + log->debug(" Direction: %s\n", (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? "Uplink" : "Downlink"); + log->debug_hex(msg, msg_len, " Message"); + switch(integ_algo) { case INTEGRITY_ALGORITHM_ID_EIA0: @@ -316,8 +329,7 @@ bool pdcp_entity::integrity_verify(uint8_t *msg, } } if (isValid){ - log->info_hex(mac_exp, 4, "MAC match (expected)"); - log->info_hex(mac, 4, "MAC match (found)"); + log->info_hex(mac_exp, 4, "MAC match"); } break; default: diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index bd0acbeff..71aed4c3a 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -1759,7 +1759,9 @@ bool rlc_am::rlc_am_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rl rlc_amd_rx_pdu_t &back = pdu->segments.back(); n = back.header.so + back.buf->N_bytes; } + if(segment->header.so != n) { + log->warning("Received PDU with SO=%d, expected %d. Discarding PDU.\n", segment->header.so, n); pool->deallocate(segment->buf); return false; } else { diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index bb6628279..8d1b653df 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -316,7 +316,7 @@ bool concat_test() return 0; } -bool segment_test() +bool segment_test(bool in_seq_rx) { srslte::log_filter log1("RLC_AM_1"); srslte::log_filter log2("RLC_AM_2"); @@ -378,22 +378,33 @@ bool segment_test() assert(0 == rlc1.get_buffer_state()); // Write PDUs into RLC2 - for(int i=0;i= 0; --i) { + rlc2.write_pdu(pdu_bufs[i].msg, pdu_bufs[i].N_bytes); + } } - assert(2 == rlc2.get_buffer_state()); + // Receiver will only generate status PDU if they arrive in order + // If SN=7 arrives first, but the Rx expects SN=0, status reporting will be delayed, see TS 36.322 v10 Section 5.2.3 + if (in_seq_rx) { + assert(2 == rlc2.get_buffer_state()); - // Read status PDU from RLC2 - byte_buffer_t status_buf; - len = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status - status_buf.N_bytes = len; + // Read status PDU from RLC2 + byte_buffer_t status_buf; + len = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + status_buf.N_bytes = len; - assert(0 == rlc2.get_buffer_state()); + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + } - // Write status PDU to RLC1 - rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + assert(0 == rlc2.get_buffer_state()); assert(tester.n_sdus == 5); for(int i=0; icleanup(); - if (segment_test()) { - printf("segment_test failed\n"); + if (segment_test(true)) { + printf("segment_test with in-order PDU reception failed\n"); + exit(-1); + }; + byte_buffer_pool::get_instance()->cleanup(); + + if (segment_test(false)) { + printf("segment_test with out-of-order PDU reception failed\n"); exit(-1); }; byte_buffer_pool::get_instance()->cleanup(); diff --git a/srsenb/src/metrics_stdout.cc b/srsenb/src/metrics_stdout.cc index 786ed1f85..e2c8bb0c0 100644 --- a/srsenb/src/metrics_stdout.cc +++ b/srsenb/src/metrics_stdout.cc @@ -67,80 +67,73 @@ void metrics_stdout::toggle_print(bool b) void metrics_stdout::set_metrics(enb_metrics_t &metrics, const uint32_t period_usec) { - if (!do_print || enb == NULL) { + if (!do_print || enb == NULL || metrics.rrc.n_ues == 0) { return; } std::ios::fmtflags f(cout.flags()); // For avoiding Coverity defect: Not restoring ostream format - if (metrics.rrc.n_ues == 0) { - cout << "--- disconnected ---" << endl; - return; - } - - if(++n_reports > 10) - { + if (++n_reports > 10) { n_reports = 0; cout << endl; cout << "------DL------------------------------UL----------------------------------" << endl; cout << "rnti cqi ri mcs brate bler snr phr mcs brate bler bsr" << endl; } - if (metrics.rrc.n_ues > 0) { - - for (int i=0;i metrics.mac[i].tx_pkts) { - printf("tx caution errors %d > %d\n", metrics.mac[i].tx_errors, metrics.mac[i].tx_pkts); - } - if (metrics.mac[i].rx_errors > metrics.mac[i].rx_pkts) { - printf("rx caution errors %d > %d\n", metrics.mac[i].rx_errors, metrics.mac[i].rx_pkts); - } - - cout << std::hex << metrics.mac[i].rnti << " "; - cout << float_to_string(SRSLTE_MAX(0.1,metrics.mac[i].dl_cqi), 2); - cout << float_to_string(metrics.mac[i].dl_ri, 1); - if(not isnan(metrics.phy[i].dl.mcs)) { - cout << float_to_string(SRSLTE_MAX(0.1,metrics.phy[i].dl.mcs), 2); - } else { - cout << float_to_string(0,2); - } - if (metrics.mac[i].tx_brate > 0) { - cout << float_to_eng_string(SRSLTE_MAX(0.1,(float) metrics.mac[i].tx_brate/period_usec*1e6), 2); - } else { - cout << float_to_string(0, 2) << ""; - } - if (metrics.mac[i].tx_pkts > 0 && metrics.mac[i].tx_errors) { - cout << float_to_string(SRSLTE_MAX(0.1,(float) 100*metrics.mac[i].tx_errors/metrics.mac[i].tx_pkts), 1) << "%"; - } else { - cout << float_to_string(0, 1) << "%"; - } - if(not isnan(metrics.phy[i].ul.sinr)) { - cout << float_to_string(SRSLTE_MAX(0.1,metrics.phy[i].ul.sinr), 2); - } else { - cout << float_to_string(0,2); - } - cout << float_to_string(metrics.mac[i].phr, 2); - if(not isnan(metrics.phy[i].ul.mcs)) { - cout << float_to_string(SRSLTE_MAX(0.1,metrics.phy[i].ul.mcs), 2); - } else { - cout << float_to_string(0,2); - } - if (metrics.mac[i].rx_brate > 0) { - cout << float_to_eng_string(SRSLTE_MAX(0.1,(float) metrics.mac[i].rx_brate/period_usec*1e6), 2); - } else { - cout << float_to_string(0, 2) << ""; - } - if (metrics.mac[i].rx_pkts > 0 && metrics.mac[i].rx_errors > 0) { - cout << float_to_string(SRSLTE_MAX(0.1,(float) 100*metrics.mac[i].rx_errors/metrics.mac[i].rx_pkts), 1) << "%"; - } else { - cout << float_to_string(0, 1) << "%"; - } - cout << float_to_eng_string(metrics.mac[i].ul_buffer, 2); - cout << endl; + + for (int i = 0; i < metrics.rrc.n_ues; i++) { + if (metrics.mac[i].tx_errors > metrics.mac[i].tx_pkts) { + printf("tx caution errors %d > %d\n", metrics.mac[i].tx_errors, metrics.mac[i].tx_pkts); } - } else { - cout << "--- No users ---" << endl; + if (metrics.mac[i].rx_errors > metrics.mac[i].rx_pkts) { + printf("rx caution errors %d > %d\n", metrics.mac[i].rx_errors, metrics.mac[i].rx_pkts); + } + + cout << std::hex << metrics.mac[i].rnti << " "; + cout << float_to_string(SRSLTE_MAX(0.1, metrics.mac[i].dl_cqi), 2); + cout << float_to_string(metrics.mac[i].dl_ri, 1); + if (not isnan(metrics.phy[i].dl.mcs)) { + cout << float_to_string(SRSLTE_MAX(0.1, metrics.phy[i].dl.mcs), 2); + } else { + cout << float_to_string(0, 2); + } + if (metrics.mac[i].tx_brate > 0) { + cout << float_to_eng_string(SRSLTE_MAX(0.1, (float)metrics.mac[i].tx_brate / period_usec * 1e6), 2); + } else { + cout << float_to_string(0, 2) << ""; + } + if (metrics.mac[i].tx_pkts > 0 && metrics.mac[i].tx_errors) { + cout << float_to_string(SRSLTE_MAX(0.1, (float)100 * metrics.mac[i].tx_errors / metrics.mac[i].tx_pkts), 1) + << "%"; + } else { + cout << float_to_string(0, 1) << "%"; + } + if (not isnan(metrics.phy[i].ul.sinr)) { + cout << float_to_string(SRSLTE_MAX(0.1, metrics.phy[i].ul.sinr), 2); + } else { + cout << float_to_string(0, 2); + } + cout << float_to_string(metrics.mac[i].phr, 2); + if (not isnan(metrics.phy[i].ul.mcs)) { + cout << float_to_string(SRSLTE_MAX(0.1, metrics.phy[i].ul.mcs), 2); + } else { + cout << float_to_string(0, 2); + } + if (metrics.mac[i].rx_brate > 0) { + cout << float_to_eng_string(SRSLTE_MAX(0.1, (float)metrics.mac[i].rx_brate / period_usec * 1e6), 2); + } else { + cout << float_to_string(0, 2) << ""; + } + if (metrics.mac[i].rx_pkts > 0 && metrics.mac[i].rx_errors > 0) { + cout << float_to_string(SRSLTE_MAX(0.1, (float)100 * metrics.mac[i].rx_errors / metrics.mac[i].rx_pkts), 1) + << "%"; + } else { + cout << float_to_string(0, 1) << "%"; + } + cout << float_to_eng_string(metrics.mac[i].ul_buffer, 2); + cout << endl; } - if(metrics.rf.rf_error) { + + if (metrics.rf.rf_error) { printf("RF status: O=%d, U=%d, L=%d\n", metrics.rf.rf_o, metrics.rf.rf_u, metrics.rf.rf_l); } diff --git a/srsenb/src/upper/rrc.cc b/srsenb/src/upper/rrc.cc index fec2f88e3..9c1ef0f18 100644 --- a/srsenb/src/upper/rrc.cc +++ b/srsenb/src/upper/rrc.cc @@ -1045,8 +1045,8 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, byte_buffer_t *pdu) void rrc::ue::handle_rrc_con_req(LIBLTE_RRC_CONNECTION_REQUEST_STRUCT *msg) { if (not parent->s1ap->is_mme_connected()) { - printf("send reject\n"); - parent->rrc_log->error("MME isn't connected. Sending Connection Reject\n"); + parent->rrc_log->error("MME isn't connected. Sending Connection Reject.\n"); + parent->rrc_log->console("MME isn't connected. Sending Connection Reject.\n"); send_connection_reject(); } @@ -1166,6 +1166,10 @@ void rrc::ue::set_security_key(uint8_t* key, uint32_t length) k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo); + + parent->rrc_log->info_hex(k_rrc_enc, 32, "RRC Encryption Key (k_rrc_enc)"); + parent->rrc_log->info_hex(k_rrc_int, 32, "RRC Integrity Key (k_rrc_int)"); + parent->rrc_log->info_hex(k_up_enc, 32, "RRC Encryption Key (k_rrc_enc)"); } bool rrc::ue::setup_erabs(LIBLTE_S1AP_E_RABTOBESETUPLISTCTXTSUREQ_STRUCT *e) diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index dff478c6b..a14b96f73 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -1253,6 +1253,8 @@ nas::pack_attach_accept(srslte::byte_buffer_t *nas_buffer) act_def_eps_bearer_context_req.transaction_id_present = false; //set eps_qos act_def_eps_bearer_context_req.eps_qos.qci = m_esm_ctx[5].qci; + act_def_eps_bearer_context_req.eps_qos.br_present = false; + act_def_eps_bearer_context_req.eps_qos.br_ext_present = false; //set apn strncpy(act_def_eps_bearer_context_req.apn.apn, m_apn.c_str(), LIBLTE_STRING_LEN); diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 2c633ef38..685ac8b78 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -85,7 +85,7 @@ public: void paging(LIBLTE_RRC_S_TMSI_STRUCT *ue_identiy); void set_barring(barring_t barring); void write_pdu(uint32_t lcid, byte_buffer_t *pdu); - uint32_t get_ul_count(); + uint32_t get_k_enb_count(); bool is_attached(); bool get_k_asme(uint8_t *k_asme_, uint32_t n); uint32_t get_ipv4_addr(); @@ -125,6 +125,7 @@ private: uint8_t k_asme[32]; uint32_t tx_count; uint32_t rx_count; + uint32_t k_enb_count; srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; @@ -163,6 +164,7 @@ private: bool integrity_check(byte_buffer_t *pdu); void cipher_encrypt(byte_buffer_t *pdu); void cipher_decrypt(byte_buffer_t *pdu); + void set_k_enb_count(uint32_t count); bool check_cap_replay(LIBLTE_MME_UE_SECURITY_CAPABILITIES_STRUCT *caps); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 97643886a..4f90e3bae 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -388,14 +388,15 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { } } -uint32_t nas::get_ul_count() { - // UL count for RRC key derivation depends on ESM information transfer procedure - if (cfg.apn.empty()) { - // No ESM info transfer has been sent - return ctxt.tx_count - 1; - } else { - return ctxt.tx_count - 2; - } +void nas::set_k_enb_count(uint32_t count) { + // UL count for RRC key derivation depends on UL Count of the Attach Request or Service Request. + // On the case of an Authentication Request, the UL count used to generate K_enb must be reset to zero. + ctxt.k_enb_count = count; + return; +} + +uint32_t nas::get_k_enb_count() { + return ctxt.k_enb_count; } bool nas::get_k_asme(uint8_t *k_asme_, uint32_t n) { @@ -886,6 +887,7 @@ void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu, const nas_log->info("Network authentication successful\n"); send_authentication_response(res, res_len, sec_hdr_type); nas_log->info_hex(ctxt.k_asme, 32, "Generated k_asme:\n"); + set_k_enb_count(0); auth_request = true; } else if (auth_result == AUTH_SYNCH_FAILURE) { nas_log->error("Network authentication synchronization failure.\n"); @@ -1176,6 +1178,7 @@ void nas::gen_attach_request(byte_buffer_t *msg) { } if (have_ctxt) { + set_k_enb_count(ctxt.tx_count); ctxt.tx_count++; } } @@ -1212,7 +1215,7 @@ void nas::gen_service_request(byte_buffer_t *msg) { if(pcap != NULL) { pcap->write_nas(msg->msg, msg->N_bytes); } - + set_k_enb_count(ctxt.tx_count); ctxt.tx_count++; } @@ -1320,6 +1323,7 @@ void nas::send_detach_request(bool switch_off) &pdu->msg[5], pdu->N_bytes - 5, &pdu->msg[1]); + ctxt.tx_count++; } else { nas_log->error("Invalid PDU size %d\n", pdu->N_bytes); } diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 454a44c2e..20bb803e8 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2075,7 +2075,9 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { // Generate AS security keys uint8_t k_asme[32]; nas->get_k_asme(k_asme, 32); - usim->generate_as_keys(k_asme, nas->get_ul_count(), k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo); + rrc_log->debug_hex(k_asme, 32, "UE K_asme"); + rrc_log->debug("Generating K_enb with UL NAS COUNT: %d\n", nas->get_k_enb_count()); + usim->generate_as_keys(k_asme, nas->get_k_enb_count(), k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo); rrc_log->info_hex(k_rrc_enc, 32, "RRC encryption key - k_rrc_enc"); rrc_log->info_hex(k_rrc_int, 32, "RRC integrity key - k_rrc_int"); rrc_log->info_hex(k_up_enc, 32, "UP encryption key - k_up_enc"); @@ -2711,7 +2713,7 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) { drbs[lcid] = *drb_cnfg; drb_up = true; - rrc_log->info("Added radio bearer %s\n", get_rb_name(lcid).c_str()); + rrc_log->info("Added radio bearer %s (LCID=%d)\n", get_rb_name(lcid).c_str(), lcid); } void rrc::release_drb(uint32_t drb_id)