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 diff --git a/lib/include/srslte/common/pdu.h b/lib/include/srslte/common/pdu.h index 5d37a0d63..5d0f5a235 100644 --- a/lib/include/srslte/common/pdu.h +++ b/lib/include/srslte/common/pdu.h @@ -133,11 +133,15 @@ 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++; - } - nof_subheaders++; + nof_subheaders = 0; + bool ret = false; + do { + if (nof_subheaders < (int)max_subheaders) { + ret = subheaders[nof_subheaders].read_subheader(&ptr); + nof_subheaders++; + } + } while (ret && (nof_subheaders + 1) < (int)max_subheaders); + for (int i=0;iwait_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); diff --git a/lib/src/common/pdu.cc b/lib/src/common/pdu.cc index b0cdef638..80db7627d 100644 --- a/lib/src/common/pdu.cc +++ b/lib/src/common/pdu.cc @@ -122,7 +122,7 @@ uint8_t* sch_pdu::write_packet(srslte::log *log_h) sch_subh padding; padding.set_padding(); - if (nof_subheaders <= 0) { + if (nof_subheaders <= 0 && nof_subheaders < (int)max_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; 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/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"])) { diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index 51f161d4a..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; } @@ -254,32 +260,42 @@ 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 + * + * 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(&mutex); - int ret = 0; - if (ue_db.count(rnti)) { + pthread_mutex_lock(&mutex2); + 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; + 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) { @@ -676,10 +692,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 +723,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; } } 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; 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; - - 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; - } + 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; + } + } + 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);