This commit is contained in:
yagoda 2018-12-04 17:49:30 +01:00
commit 77fb9c3ad5
22 changed files with 224 additions and 127 deletions

View File

@ -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")

View File

@ -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 <immintrin.h>
int main()

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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 */

View File

@ -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) {

View File

@ -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;td<SRSLTE_TDEC_NOF_AUTO_MODES_16;td++) {
if (h->dec16[td]) {
if ((h->nof_blocks16[td] = h->dec16[td]->tdec_init(&h->dec16_hdlr[td], h->max_long_cb))<0) {

View File

@ -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 */

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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++;

View File

@ -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];
}

View File

@ -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:

View File

@ -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 {

View File

@ -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,23 +378,34 @@ bool segment_test()
assert(0 == rlc1.get_buffer_state());
// Write PDUs into RLC2
for(int i=0;i<n_pdus;i++)
{
rlc2.write_pdu(pdu_bufs[i].msg, pdu_bufs[i].N_bytes);
if (in_seq_rx) {
// deliver PDUs in order
for (int i = 0; i < n_pdus; ++i) {
rlc2.write_pdu(pdu_bufs[i].msg, pdu_bufs[i].N_bytes);
}
} else {
// deliver PDUs in reverse order
for (int i = n_pdus - 1; 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;
// Write status PDU to RLC1
rlc1.write_pdu(status_buf.msg, status_buf.N_bytes);
}
assert(0 == rlc2.get_buffer_state());
// Write status PDU to RLC1
rlc1.write_pdu(status_buf.msg, status_buf.N_bytes);
assert(tester.n_sdus == 5);
for(int i=0; i<tester.n_sdus; i++)
{
@ -1706,8 +1717,14 @@ int main(int argc, char **argv)
};
byte_buffer_pool::get_instance()->cleanup();
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();

View File

@ -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.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);
}
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);
}

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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)