From 682ed433b212b7b0aee682cacb3c2831f3f7260c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 18 Mar 2018 13:24:09 +0100 Subject: [PATCH 1/9] Possible fix to #167 --- lib/include/srslte/common/pdu.h | 11 ++++++++--- lib/src/common/pdu.cc | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/include/srslte/common/pdu.h b/lib/include/srslte/common/pdu.h index 5d37a0d63..20fe91816 100644 --- a/lib/include/srslte/common/pdu.h +++ b/lib/include/srslte/common/pdu.h @@ -133,11 +133,16 @@ public: // Section 6.1.2 void parse_packet(uint8_t *ptr) { uint8_t *init_ptr = ptr; - nof_subheaders = 0; - while(subheaders[nof_subheaders].read_subheader(&ptr)) { + nof_subheaders = 0; + bool ret = false; + do { + if (nof_subheaders < (int) max_subheaders) { + ret = subheaders[nof_subheaders].read_subheader(&ptr); + } + } while (ret && nof_subheaders < (int) max_subheaders); + if (nof_subheaders + 1 < (int) max_subheaders) { nof_subheaders++; } - nof_subheaders++; for (int i=0;ierror("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; From 37e06d78ead5e87d3050fb57d2aa1251ecfed91f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 19 Mar 2018 13:21:36 +0100 Subject: [PATCH 2/9] fix build_mode printing in RelWithDebInfo mode --- CMakeLists.txt | 16 ++++++---------- lib/include/srslte/build_info.h.in | 12 ++++++++++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a91e11da7..98023d7b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -231,12 +231,6 @@ endmacro(ADD_CXX_COMPILER_FLAG_IF_AVAILABLE) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable -std=c++03") - if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -DDEBUG_MODE") - else(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") - endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - find_package(SSE) if (HAVE_AVX2) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -mavx2 -DLV_HAVE_AVX2 -DLV_HAVE_AVX -DLV_HAVE_SSE") @@ -255,16 +249,18 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-write-strings -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE") if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -DDEBUG_MODE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -O0 -DDEBUG_MODE -DBUILD_TYPE_DEBUG") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -O0 -DDEBUG_MODE -DBUILD_TYPE_DEBUG") else(${CMAKE_BUILD_TYPE} STREQUAL "Debug") if(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG_MODE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -DBUILD_TYPE_RELWITHDEBINFO") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -DBUILD_TYPE_RELWITHDEBINFO") else(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -DBUILD_TYPE_RELEASE") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -DBUILD_TYPE_RELEASE") 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") diff --git a/lib/include/srslte/build_info.h.in b/lib/include/srslte/build_info.h.in index a8acb306b..90dac1dbb 100644 --- a/lib/include/srslte/build_info.h.in +++ b/lib/include/srslte/build_info.h.in @@ -32,10 +32,18 @@ extern "C" { # endif -#ifdef NDEBUG - static char build_mode[] = "Release"; +#ifdef BUILD_TYPE_RELEASE + static char build_mode[] = "Release"; #else + #ifdef BUILD_TYPE_DEBUG static char build_mode[] = "Debug"; + #else + #ifdef BUILD_TYPE_RELWITHDEBINFO + static char build_mode[] = "RelWithDebInfo"; + #else + static char build_mode[] = "unknown"; + #endif + #endif #endif // the configured build options for srsLTE From 8b04d7c308e707536ab02d291d83062b55f311f0 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 19 Mar 2018 13:25:33 +0100 Subject: [PATCH 3/9] fix compile warning --- 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 8227a2882..0df792fd5 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -1150,7 +1150,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 < (int) sf_len*max_sf) { + if (offset >= 0 && offset < (int)(sf_len*max_sf)) { uint32_t nof_sf = (sf_len*max_sf - offset)/sf_len; From c5b423ffee5e852a5e4c82c6369fbf409d59243b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 19 Mar 2018 14:38:27 +0100 Subject: [PATCH 4/9] fix subheader parsing --- lib/include/srslte/common/pdu.h | 9 ++++----- lib/src/common/pdu.cc | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/include/srslte/common/pdu.h b/lib/include/srslte/common/pdu.h index 20fe91816..5d0f5a235 100644 --- a/lib/include/srslte/common/pdu.h +++ b/lib/include/srslte/common/pdu.h @@ -136,13 +136,12 @@ public: nof_subheaders = 0; bool ret = false; do { - if (nof_subheaders < (int) max_subheaders) { + if (nof_subheaders < (int)max_subheaders) { ret = subheaders[nof_subheaders].read_subheader(&ptr); + nof_subheaders++; } - } while (ret && nof_subheaders < (int) max_subheaders); - if (nof_subheaders + 1 < (int) max_subheaders) { - nof_subheaders++; - } + } while (ret && (nof_subheaders + 1) < (int)max_subheaders); + for (int i=0;ierror("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; From daf0a113456c4dac4311ef9b3f7e5c8b7fd69b2c Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Tue, 20 Mar 2018 12:47:00 +0000 Subject: [PATCH 5/9] Fix for RRC Connection Reject wait time pack/unpack --- lib/src/asn1/liblte_rrc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/asn1/liblte_rrc.cc b/lib/src/asn1/liblte_rrc.cc index c53399384..74beb46cf 100644 --- a/lib/src/asn1/liblte_rrc.cc +++ b/lib/src/asn1/liblte_rrc.cc @@ -11771,7 +11771,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_rrc_connection_reject_msg(LIBLTE_RRC_CONNECTIO liblte_value_2_bits(0, &msg_ptr, 1); // Wait Time - liblte_value_2_bits(con_rej->wait_time, &msg_ptr, 4); + liblte_value_2_bits(con_rej->wait_time - 1, &msg_ptr, 4); // Fill in the number of bits used msg->N_bits = msg_ptr - msg->msg; @@ -11800,7 +11800,7 @@ LIBLTE_ERROR_ENUM liblte_rrc_unpack_rrc_connection_reject_msg(LIBLTE_BIT_MSG_STR liblte_rrc_warning_not_handled(liblte_bits_2_value(&msg_ptr, 1), __func__);; // Wait Time - con_rej->wait_time = liblte_bits_2_value(&msg_ptr, 4); + con_rej->wait_time = liblte_bits_2_value(&msg_ptr, 4) + 1; liblte_rrc_consume_noncrit_extension(ext, __func__, &msg_ptr); From 2d9c10102714b4fbb1b5dbe46346712331f9257b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Mar 2018 11:42:37 +0100 Subject: [PATCH 6/9] Check all DRB config parameters --- srsenb/src/enb_cfg_parser.cc | 48 +++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 669d2586b..b63c46058 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1072,7 +1072,9 @@ int field_qci::parse(libconfig::Setting &root) parser::field_enum_num sn_field_len ("sn_field_length", &rlc_cfg->sn_field_len, liblte_rrc_sn_field_length_num, LIBLTE_RRC_SN_FIELD_LENGTH_N_ITEMS); - sn_field_len.parse(q["rlc_config"]["ul_um"]); + if (sn_field_len.parse(q["rlc_config"]["ul_um"])) { + fprintf(stderr, "Error can't find sn_field_length in section ul_um\n"); + } } if (q["rlc_config"].exists("dl_um")) { @@ -1085,12 +1087,16 @@ int field_qci::parse(libconfig::Setting &root) parser::field_enum_num sn_field_len ("sn_field_length", &rlc_cfg->sn_field_len, liblte_rrc_sn_field_length_num, LIBLTE_RRC_SN_FIELD_LENGTH_N_ITEMS); - sn_field_len.parse(q["rlc_config"]["dl_um"]); + if (sn_field_len.parse(q["rlc_config"]["dl_um"])) { + fprintf(stderr, "Error can't find sn_field_length in section dl_um\n"); + } parser::field_enum_num t_reordering ("t_reordering", &rlc_cfg->t_reordering, liblte_rrc_t_reordering_num, LIBLTE_RRC_T_REORDERING_N_ITEMS); - t_reordering.parse(q["rlc_config"]["dl_um"]); + if (t_reordering.parse(q["rlc_config"]["dl_um"])) { + fprintf(stderr, "Error can't find t_reordering in section dl_um\n"); + } } // Parse RLC-AM section @@ -1100,22 +1106,30 @@ int field_qci::parse(libconfig::Setting &root) parser::field_enum_num t_poll_retx ("t_poll_retx", &rlc_cfg->t_poll_retx, liblte_rrc_t_poll_retransmit_num, LIBLTE_RRC_T_POLL_RETRANSMIT_N_ITEMS); - t_poll_retx.parse(q["rlc_config"]["ul_am"]); + if (t_poll_retx.parse(q["rlc_config"]["ul_am"])) { + fprintf(stderr, "Error can't find t_poll_retx in section ul_am\n"); + } parser::field_enum_num poll_pdu ("poll_pdu", &rlc_cfg->poll_pdu, liblte_rrc_poll_pdu_num, LIBLTE_RRC_POLL_PDU_N_ITEMS); - poll_pdu.parse(q["rlc_config"]["ul_am"]); + if (poll_pdu.parse(q["rlc_config"]["ul_am"])) { + fprintf(stderr, "Error can't find poll_pdu in section ul_am\n"); + } parser::field_enum_num poll_byte ("poll_byte", &rlc_cfg->poll_byte, liblte_rrc_poll_byte_num, LIBLTE_RRC_POLL_BYTE_N_ITEMS); - poll_byte.parse(q["rlc_config"]["ul_am"]); + if (poll_byte.parse(q["rlc_config"]["ul_am"])) { + fprintf(stderr, "Error can't find poll_byte in section ul_am\n"); + } parser::field_enum_num max_retx_thresh ("max_retx_thresh", &rlc_cfg->max_retx_thresh, liblte_rrc_max_retx_threshold_num, LIBLTE_RRC_MAX_RETX_THRESHOLD_N_ITEMS); - max_retx_thresh.parse(q["rlc_config"]["ul_am"]); + if (max_retx_thresh.parse(q["rlc_config"]["ul_am"])) { + fprintf(stderr, "Error can't find max_retx_thresh in section ul_am\n"); + } } if (q["rlc_config"].exists("dl_am")) { @@ -1124,12 +1138,16 @@ int field_qci::parse(libconfig::Setting &root) parser::field_enum_num t_reordering ("t_reordering", &rlc_cfg->t_reordering, liblte_rrc_t_reordering_num, LIBLTE_RRC_T_REORDERING_N_ITEMS); - t_reordering.parse(q["rlc_config"]["dl_am"]); + if (t_reordering.parse(q["rlc_config"]["dl_am"])) { + fprintf(stderr, "Error can't find t_reordering in section dl_am\n"); + } parser::field_enum_num t_status_prohibit ("t_status_prohibit", &rlc_cfg->t_status_prohibit, liblte_rrc_t_status_prohibit_num, LIBLTE_RRC_T_STATUS_PROHIBIT_N_ITEMS); - t_status_prohibit.parse(q["rlc_config"]["dl_am"]); + if (t_status_prohibit.parse(q["rlc_config"]["dl_am"])) { + fprintf(stderr, "Error can't find t_status_prohibit in section dl_am\n"); + } } @@ -1141,17 +1159,23 @@ int field_qci::parse(libconfig::Setting &root) LIBLTE_RRC_UL_SPECIFIC_PARAMETERS_STRUCT *lc_cfg = &cfg[qci].lc_cfg; parser::field priority ("priority", &lc_cfg->priority); - priority.parse(q["logical_channel_config"]); + if (priority.parse(q["logical_channel_config"])) { + fprintf(stderr, "Error can't find logical_channel_config in section priority\n"); + } parser::field_enum_num prioritized_bit_rate ("prioritized_bit_rate", &lc_cfg->prioritized_bit_rate, liblte_rrc_prioritized_bit_rate_num, LIBLTE_RRC_PRIORITIZED_BIT_RATE_N_ITEMS); - prioritized_bit_rate.parse(q["logical_channel_config"]); + if (prioritized_bit_rate.parse(q["logical_channel_config"])) { + fprintf(stderr, "Error can't find prioritized_bit_rate in section logical_channel_config\n"); + } parser::field_enum_num bucket_size_duration ("bucket_size_duration", &lc_cfg->bucket_size_duration, liblte_rrc_bucket_size_duration_num, LIBLTE_RRC_BUCKET_SIZE_DURATION_N_ITEMS); - bucket_size_duration.parse(q["logical_channel_config"]); + if (bucket_size_duration.parse(q["logical_channel_config"])) { + fprintf(stderr, "Error can't find bucket_size_duration in section logical_channel_config\n"); + } parser::field log_chan_group ("log_chan_group", &lc_cfg->log_chan_group); if (log_chan_group.parse(q["logical_channel_config"])) { From f4243656c913369b6d9acdcae0653862103c1626 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Mar 2018 11:47:30 +0100 Subject: [PATCH 7/9] Check integrity_generate msg_size parameter --- srsue/src/upper/nas.cc | 90 +++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 27 deletions(-) diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 763515ea4..7069f4a23 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -345,30 +345,38 @@ void nas::integrity_generate(uint8_t *key_128, bool nas::integrity_check(byte_buffer_t *pdu) { - uint8_t exp_mac[4]; - uint8_t *mac = &pdu->msg[1]; - int i; + if (!pdu) { + nas_log->error("Invalid PDU\n"); + return NULL; + } + if (pdu->N_bytes > 5) { + uint8_t exp_mac[4]; + uint8_t *mac = &pdu->msg[1]; + int i; - integrity_generate(&k_nas_int[16], - ctxt.rx_count, - SECURITY_DIRECTION_DOWNLINK, - &pdu->msg[5], - pdu->N_bytes-5, - &exp_mac[0]); - - // Check if expected mac equals the sent mac - for(i=0; i<4; i++){ - if(exp_mac[i] != mac[i]){ - nas_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " - "Received: count=%d, [%02x %02x %02x %02x]\n", - ctxt.rx_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3], - pdu->msg[5], mac[0], mac[1], mac[2], mac[3]); - return false; + integrity_generate(&k_nas_int[16], + ctxt.rx_count, + SECURITY_DIRECTION_DOWNLINK, + &pdu->msg[5], + pdu->N_bytes-5, + &exp_mac[0]); + + // Check if expected mac equals the sent mac + for(i=0; i<4; i++){ + if(exp_mac[i] != mac[i]){ + nas_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " + "Received: count=%d, [%02x %02x %02x %02x]\n", + ctxt.rx_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3], + pdu->msg[5], mac[0], mac[1], mac[2], mac[3]); + return false; + } } + nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n", + ctxt.rx_count, pdu->msg[5]); + return true; + } else { + nas_log->error("Invalid integrity check PDU size (%d)\n", pdu->N_bytes); } - nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n", - ctxt.rx_count, pdu->msg[5]); - return true; } void nas::cipher_encrypt(byte_buffer_t *pdu) @@ -454,6 +462,17 @@ bool nas::check_cap_replay(LIBLTE_MME_UE_SECURITY_CAPABILITIES_STRUCT *caps) ******************************************************************************/ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) { + + if (!pdu) { + nas_log->error("Invalid PDU\n"); + return; + } + + if (pdu->N_bytes <= 5) { + nas_log->error("Invalid attach accept PDU size (%d)\n", pdu->N_bytes); + return; + } + LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept; LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req; LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_complete; @@ -679,6 +698,17 @@ void nas::parse_identity_request(uint32_t lcid, byte_buffer_t *pdu) { void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu) { + + if (!pdu) { + nas_log->error("Invalid PDU\n"); + return; + } + + if (pdu->N_bytes <= 5) { + nas_log->error("Invalid security mode command PDU size (%d)\n", pdu->N_bytes); + return; + } + LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sec_mode_cmd; LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp; @@ -808,6 +838,8 @@ 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) { @@ -861,12 +893,16 @@ void nas::send_attach_request() { (LIBLTE_BYTE_MSG_STRUCT *) msg); // Add MAC - integrity_generate(&k_nas_int[16], - ctxt.tx_count, - SECURITY_DIRECTION_UPLINK, - &msg->msg[5], - msg->N_bytes - 5, - &msg->msg[1]); + if (msg->N_bytes > 5) { + integrity_generate(&k_nas_int[16], + ctxt.tx_count, + SECURITY_DIRECTION_UPLINK, + &msg->msg[5], + msg->N_bytes - 5, + &msg->msg[1]); + } else { + nas_log->error("Invalid PDU size %d\n", msg->N_bytes); + } } else { attach_req.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI; usim->get_imsi_vec(attach_req.eps_mobile_id.imsi, 15); From 45cae1d1aba068fe4a9f3a3dc424fee6b51dc47d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Mar 2018 13:10:13 +0100 Subject: [PATCH 8/9] Fix srsENB DL TCP stalling --- srsenb/src/mac/scheduler.cc | 27 +++++++++++++++++---------- srsenb/src/mac/scheduler_metric.cc | 4 +--- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index 51f161d4a..995363045 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -254,18 +254,22 @@ uint32_t sched::get_ul_buffer(uint16_t rnti) return ret; } +/* \Warning: This function is not mutexed because it can produce late changes on the buffer state while + * the scheduler is already allocating data, resulting in empty grants. + * Ideally we would like the scheduler to query the RLC for buffer states in order to get the most updated + * buffer state with the minimum overhead. However, the current architecture is designed to be compliant + * with the FAPI interface + */ int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) { - pthread_mutex_lock(&mutex); - int ret = 0; - if (ue_db.count(rnti)) { + int ret = 0; + if (ue_db.count(rnti)) { ue_db[rnti].dl_buffer_state(lc_id, tx_queue, retx_queue); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } - pthread_mutex_unlock(&mutex); - return ret; + return ret; } int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code) @@ -676,10 +680,11 @@ int sched::dl_sched_data(dl_sched_data_t data[MAX_DATA_LIST]) int nof_data_elems = 0; for(std::map::iterator iter=ue_db.begin(); iter!=ue_db.end(); ++iter) { - sched_ue *user = (sched_ue*) &iter->second; - uint16_t rnti = (uint16_t) iter->first; + sched_ue *user = (sched_ue*) &iter->second; + uint16_t rnti = (uint16_t) iter->first; - dl_harq_proc *h = dl_metric->get_user_allocation(user); + uint32_t data_before = user->get_pending_dl_new_data(current_tti); + dl_harq_proc *h = dl_metric->get_user_allocation(user); srslte_dci_format_t dci_format = user->get_dci_format(); data[nof_data_elems].dci_format = dci_format; @@ -706,10 +711,12 @@ int sched::dl_sched_data(dl_sched_data_t data[MAX_DATA_LIST]) Error("DCI format (%d) not implemented\n", dci_format); } if (tbs > 0) { - log_h->info("SCHED: DL %s rnti=0x%x, pid=%d, mask=0x%x, dci=%d,%d, n_rtx=%d, tbs=%d, buffer=%d, tb_en={%s,%s}\n", + log_h->info("SCHED: DL %s rnti=0x%x, pid=%d, mask=0x%x, dci=%d,%d, n_rtx=%d, tbs=%d, buffer=%d/%d, tb_en={%s,%s}\n", !is_newtx?"retx":"tx", rnti, h->get_id(), h->get_rbgmask(), data[nof_data_elems].dci_location.L, data[nof_data_elems].dci_location.ncce, h->nof_retx(0) + h->nof_retx(1), - tbs, user->get_pending_dl_new_data(current_tti), data[nof_data_elems].dci.tb_en[0]?"y":"n", + tbs, + data_before, user->get_pending_dl_new_data(current_tti), + data[nof_data_elems].dci.tb_en[0]?"y":"n", data[nof_data_elems].dci.tb_en[1]?"y":"n"); nof_data_elems++; } else { diff --git a/srsenb/src/mac/scheduler_metric.cc b/srsenb/src/mac/scheduler_metric.cc index f6fb9d9df..1d9cdb954 100644 --- a/srsenb/src/mac/scheduler_metric.cc +++ b/srsenb/src/mac/scheduler_metric.cc @@ -148,9 +148,7 @@ dl_harq_proc* dl_metric_rr::get_user_allocation(sched_ue *user) if (pending_data || (h && !h->is_empty())) { #endif if (nof_users_with_data) { - if (nof_users_with_data == 2) { - } - if ((current_tti%nof_users_with_data) != user->ue_idx) { + if ((current_tti%nof_users_with_data) != user->ue_idx) { return NULL; } } From fa4d14652de0482b94b08df1f16a5a03899a124c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 21 Mar 2018 13:32:19 +0100 Subject: [PATCH 9/9] Added mutex for ue_rem/buffer access for more safety --- srsenb/hdr/mac/scheduler.h | 6 +++--- srsenb/src/mac/scheduler.cc | 24 ++++++++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/srsenb/hdr/mac/scheduler.h b/srsenb/hdr/mac/scheduler.h index c3ca7d624..12c336c36 100644 --- a/srsenb/hdr/mac/scheduler.h +++ b/srsenb/hdr/mac/scheduler.h @@ -100,8 +100,8 @@ public: uint32_t get_ul_buffer(uint16_t rnti); uint32_t get_dl_buffer(uint16_t rnti); - int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue); - int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code); + int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue); + int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code); int dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dedicated); int dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t tb_idx, bool ack); @@ -217,7 +217,7 @@ private: bool configured; - pthread_mutex_t mutex; + pthread_mutex_t mutex, mutex2; }; diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index 995363045..2e0504193 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -64,6 +64,7 @@ sched::sched() : bc_aggr_level(0), rar_aggr_level(0), avail_rbg(0), P(0), start_ } pthread_mutex_init(&mutex, NULL); + pthread_mutex_init(&mutex2, NULL); reset(); } @@ -71,6 +72,7 @@ sched::~sched() { srslte_regs_free(®s); pthread_mutex_destroy(&mutex); + pthread_mutex_destroy(&mutex2); } void sched::init(rrc_interface_mac *rrc_, srslte::log* log) @@ -173,13 +175,15 @@ int sched::ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t *ue_cfg) int sched::ue_rem(uint16_t rnti) { pthread_mutex_lock(&mutex); - int ret = 0; + pthread_mutex_lock(&mutex2); + int ret = 0; if (ue_db.count(rnti)) { ue_db.erase(rnti); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex); return ret; } @@ -217,13 +221,15 @@ int sched::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bear int sched::bearer_ue_rem(uint16_t rnti, uint32_t lc_id) { pthread_mutex_lock(&mutex); - int ret = 0; + pthread_mutex_lock(&mutex2); + int ret = 0; if (ue_db.count(rnti)) { ue_db[rnti].rem_bearer(lc_id); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex); return ret; } @@ -259,9 +265,13 @@ uint32_t sched::get_ul_buffer(uint16_t rnti) * Ideally we would like the scheduler to query the RLC for buffer states in order to get the most updated * buffer state with the minimum overhead. However, the current architecture is designed to be compliant * with the FAPI interface + * + * We add a new mutex used only in ue_rem to avoid the UE being removed in between the access to + * ue_db.count() and the access to the std::map. */ int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) { + pthread_mutex_lock(&mutex2); int ret = 0; if (ue_db.count(rnti)) { ue_db[rnti].dl_buffer_state(lc_id, tx_queue, retx_queue); @@ -269,21 +279,23 @@ int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_mutex_unlock(&mutex2); return ret; } +/* \Warning Read comment in dl_rlc_buffer_state() */ int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code) { - pthread_mutex_lock(&mutex); - int ret = 0; + pthread_mutex_lock(&mutex2); + int ret = 0; if (ue_db.count(rnti)) { ue_db[rnti].mac_buffer_state(ce_code); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } - pthread_mutex_unlock(&mutex); - return ret; + pthread_mutex_unlock(&mutex2); + return ret; } int sched::dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dl_ant_info) {