diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 8f7445d2e8..ae4a096554 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -7,7 +7,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04, ubuntu-18.04] + os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04] compiler: [gcc, clang] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..b5d08a1faa --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,68 @@ +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master" ] + schedule: + - cron: '38 10 * * 2' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install dependencies + run: | + sudo apt-get install \ + build-essential \ + cmake \ + libfftw3-dev \ + libmbedtls-dev \ + libpcsclite-dev \ + libboost-program-options-dev \ + libconfig++-dev \ + libsctp-dev \ + libuhd-dev \ + libzmq3-dev + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.lgtm.yml b/.lgtm.yml deleted file mode 100644 index 3edf9c2091..0000000000 --- a/.lgtm.yml +++ /dev/null @@ -1,23 +0,0 @@ -extraction: - cpp: - prepare: - packages: - - build-essential - - cmake - - libfftw3-dev - - libmbedtls-dev - - libpcsclite-dev - - libboost-program-options-dev - - libconfig++-dev - - libsctp-dev - - libuhd-dev - - libzmq3-dev - configure: - command: - - mkdir build - - cd build - - cmake .. - index: - build_command: - - cd build - - make diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e53a2a7db0..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -dist: bionic -sudo: required - -before_script: - - sudo apt-get -qq update - - sudo apt-get install -qq build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libconfig++-dev libsctp-dev libczmq-dev libpcsclite-dev rapidjson-dev colordiff ninja-build clang-format-8 - -language: cpp - -compiler: - - gcc - - clang - -script: - - sudo ln -s /usr/bin/clang-format-diff-8 /usr/bin/clang-format-diff - - git remote set-branches --add origin master - - git fetch - - | - if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then - # Run only for PRs because target branch is needed to do the clang-format check - echo "Checking clang-format between TRAVIS_BRANCH=$TRAVIS_BRANCH and TRAVIS_PULL_REQUEST_BRANCH=$TRAVIS_PULL_REQUEST_BRANCH" - ./run-clang-format-diff.sh "$TRAVIS_BRANCH" "$TRAVIS_PULL_REQUEST_BRANCH" - else - echo "Skipping clang-format check" - fi - - mkdir build - - cd build - - cmake -DENABLE_TTCN3=True -DRF_FOUND=True -G Ninja .. - - ninja - - ninja test - - sudo ninja install \ No newline at end of file diff --git a/CHANGELOG b/CHANGELOG index 202e5d490c..cc331753d0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,17 @@ Change Log for Releases ======================= +## 22.10 + * Fix DL NAS integrity checks in srsUE + * Remove Travis and LGTM as CI platforms + * Remove polarssl as optional dependency (only mbedTLS used and required for security) + * Allow to specify multiple PLMNs in SIB1 + * Allow non-blocking S1AP connect and expose various other SCTP options + * Add support to broadcast MAC backoff indicator + * Seperate T300/T301 timer in srsENB + * Fix in eMBMS payload buffer handling + * Fix memleak in NR scheduler + ## 22.04.1 * Various bug fixes in RLC AM and PDCP for NR * Fix crash when UE attempted to reestablish in SA diff --git a/CMakeLists.txt b/CMakeLists.txt index b3e9909b29..85b10d9b04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,29 +180,17 @@ else(USE_MKL) endif(USE_MKL) # Crypto -find_package(Polarssl) -if (POLARSSL_FOUND) - set(SEC_INCLUDE_DIRS "${POLARSSL_INCLUDE_DIRS}") +find_package(MbedTLS REQUIRED) +if (MBEDTLS_FOUND) + set(SEC_INCLUDE_DIRS "${MBEDTLS_INCLUDE_DIRS}") if(BUILD_STATIC) - set(SEC_LIBRARIES "${POLARSSL_STATIC_LIBRARIES}") + set(SEC_LIBRARIES "${MBEDTLS_STATIC_LIBRARIES}") else(BUILD_STATIC) - set(SEC_LIBRARIES "${POLARSSL_LIBRARIES}") + set(SEC_LIBRARIES "${MBEDTLS_LIBRARIES}") endif(BUILD_STATIC) - add_definitions(-DHAVE_POLARSSL) -else(POLARSSL_FOUND) - find_package(MbedTLS REQUIRED) - if (MBEDTLS_FOUND) - set(SEC_INCLUDE_DIRS "${MBEDTLS_INCLUDE_DIRS}") - if(BUILD_STATIC) - set(SEC_LIBRARIES "${MBEDTLS_STATIC_LIBRARIES}") - else(BUILD_STATIC) - set(SEC_LIBRARIES "${MBEDTLS_LIBRARIES}") - endif(BUILD_STATIC) - add_definitions(-DHAVE_MBEDTLS) - else(MBEDTLS_FOUND) - message(FATAL_ERROR "Either PolarSSL or mbedTLS are required to build srsRAN") - endif (MBEDTLS_FOUND) -endif(POLARSSL_FOUND) +else(MBEDTLS_FOUND) + message(FATAL_ERROR "mbedTLS is required to build srsRAN") +endif (MBEDTLS_FOUND) # Hard-SIM support if(ENABLE_HARDSIM) diff --git a/README.md b/README.md index ed6633c169..1f94b98917 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ srsRAN ====== -[![Build Status](https://github.com/srsran/srsRAN/actions/workflows/ccpp.yml/badge.svg?branch=master)](https://github.com/srsran/srsRAN/actions) -[![Build Status](https://app.travis-ci.com/srsran/srsRAN.svg?branch=master)](https://app.travis-ci.com/github/srsran/srsRAN) -[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/srsran/srsRAN.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/srsran/srsRAN/context:cpp) +[![Build Status](https://github.com/srsran/srsRAN/actions/workflows/ccpp.yml/badge.svg?branch=master)](https://github.com/srsran/srsRAN/actions/workflows/ccpp.yml) +[![CodeQL](https://github.com/srsran/srsRAN/actions/workflows/codeql.yml/badge.svg?branch=master)](https://github.com/srsran/srsRAN/actions/workflows/codeql.yml) [![Coverity](https://scan.coverity.com/projects/23045/badge.svg)](https://scan.coverity.com/projects/srsran) srsRAN is a 4G/5G software radio suite developed by [SRS](http://www.srs.io). diff --git a/cmake/modules/FindPolarssl.cmake b/cmake/modules/FindPolarssl.cmake deleted file mode 100644 index a9eba4cd73..0000000000 --- a/cmake/modules/FindPolarssl.cmake +++ /dev/null @@ -1,73 +0,0 @@ -# -# Copyright 2013-2022 Software Radio Systems Limited -# -# This file is part of srsRAN -# -# srsRAN is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of -# the License, or (at your option) any later version. -# -# srsRAN is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# A copy of the GNU Affero General Public License can be found in -# the LICENSE file in the top-level directory of this distribution -# and at http://www.gnu.org/licenses/. -# - -# - Try to find polarssl -# -# Once done this will define -# POLARSSL_FOUND - System has polarssl -# POLARSSL_INCLUDE_DIRS - The polarssl include directories -# POLARSSL_LIBRARIES - The polarssl library - -FIND_PACKAGE(PkgConfig REQUIRED) -PKG_CHECK_MODULES(PC_POLARSSL polarssl) - -FIND_PATH( - POLARSSL_INCLUDE_DIRS - NAMES polarssl/version.h - HINTS $ENV{POLARSSL_DIR}/include - ${PC_POLARSSL_INCLUDEDIR} - ${CMAKE_INSTALL_PREFIX}/include - PATHS /usr/local/include - /usr/include -) - -FIND_LIBRARY( - POLARSSL_LIBRARIES - NAMES polarssl - HINTS $ENV{POLARSSL_DIR}/lib - ${PC_POLARSSL_LIBDIR} - ${CMAKE_INSTALL_PREFIX}/lib - ${CMAKE_INSTALL_PREFIX}/lib64 - PATHS /usr/local/lib - /usr/local/lib64 - /usr/lib - /usr/lib64 -) - -FIND_LIBRARY( - POLARSSL_STATIC_LIBRARIES - NAMES libpolarssl.a - HINTS $ENV{POLARSSL_DIR}/lib - ${PC_POLARSSL_LIBDIR} - ${CMAKE_INSTALL_PREFIX}/lib - ${CMAKE_INSTALL_PREFIX}/lib64 - PATHS /usr/local/lib - /usr/local/lib64 - /usr/lib - /usr/lib64 -) - -message(STATUS "POLARSSL LIBRARIES: " ${POLARSSL_LIBRARIES}) -message(STATUS "POLARSSL STATIC LIBRARIES: " ${POLARSSL_STATIC_LIBRARIES}) -message(STATUS "POLARSSL INCLUDE DIRS: " ${POLARSSL_INCLUDE_DIRS}) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Polarssl DEFAULT_MSG POLARSSL_LIBRARIES POLARSSL_INCLUDE_DIRS) -MARK_AS_ADVANCED(POLARSSL_STATIC_LIBRARIES POLARSSL_LIBRARIES POLARSSL_INCLUDE_DIRS) diff --git a/cmake/modules/SRSRANVersion.cmake b/cmake/modules/SRSRANVersion.cmake index 7a259ecbb1..21f67c5a71 100644 --- a/cmake/modules/SRSRANVersion.cmake +++ b/cmake/modules/SRSRANVersion.cmake @@ -19,7 +19,7 @@ # SET(SRSRAN_VERSION_MAJOR 22) -SET(SRSRAN_VERSION_MINOR 04) -SET(SRSRAN_VERSION_PATCH 1) +SET(SRSRAN_VERSION_MINOR 10) +SET(SRSRAN_VERSION_PATCH 0) SET(SRSRAN_VERSION_STRING "${SRSRAN_VERSION_MAJOR}.${SRSRAN_VERSION_MINOR}.${SRSRAN_VERSION_PATCH}") SET(SRSRAN_SOVERSION 0) diff --git a/lib/include/srsran/common/ssl.h b/lib/include/srsran/common/ssl.h index f00d24da39..db91f9cc17 100644 --- a/lib/include/srsran/common/ssl.h +++ b/lib/include/srsran/common/ssl.h @@ -22,25 +22,6 @@ #ifndef SRSRAN_SSL_H #define SRSRAN_SSL_H -#ifdef HAVE_POLARSSL - -#include "polarssl/aes.h" -#include "polarssl/sha256.h" - -inline void sha256(const unsigned char* key, - size_t keylen, - const unsigned char* input, - size_t ilen, - unsigned char output[32], - int is224) -{ - sha256_hmac(key, keylen, input, ilen, output, is224); -} - -#endif // HAVE_POLARSSL - -#ifdef HAVE_MBEDTLS - #include "mbedtls/aes.h" #include "mbedtls/md.h" @@ -80,6 +61,4 @@ inline void sha256(const unsigned char* key, mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), key, keylen, input, ilen, output); } -#endif // HAVE_MBEDTLS - #endif // SRSRAN_SSL_H diff --git a/lib/include/srsran/interfaces/enb_rlc_interfaces.h b/lib/include/srsran/interfaces/enb_rlc_interfaces.h index 4cab5eed0b..f49ada1be2 100644 --- a/lib/include/srsran/interfaces/enb_rlc_interfaces.h +++ b/lib/include/srsran/interfaces/enb_rlc_interfaces.h @@ -60,7 +60,7 @@ class rlc_interface_rrc virtual void clear_buffer(uint16_t rnti) = 0; virtual void add_user(uint16_t rnti) = 0; virtual void rem_user(uint16_t rnti) = 0; - virtual void add_bearer(uint16_t rnti, uint32_t lcid, srsran::rlc_config_t cnfg) = 0; + virtual void add_bearer(uint16_t rnti, uint32_t lcid, const srsran::rlc_config_t& cnfg) = 0; virtual void add_bearer_mrb(uint16_t rnti, uint32_t lcid) = 0; virtual void del_bearer(uint16_t rnti, uint32_t lcid) = 0; virtual void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) = 0; diff --git a/lib/include/srsran/interfaces/enb_s1ap_interfaces.h b/lib/include/srsran/interfaces/enb_s1ap_interfaces.h index 62a25a4b9c..e1d0457e8b 100644 --- a/lib/include/srsran/interfaces/enb_s1ap_interfaces.h +++ b/lib/include/srsran/interfaces/enb_s1ap_interfaces.h @@ -42,6 +42,7 @@ struct s1ap_args_t { uint32_t ts1_reloc_prep_timeout; uint32_t ts1_reloc_overall_timeout; int32_t max_s1_setup_retries; + uint32_t s1_connect_timer; bool sctp_reuse_addr; int32_t sctp_rto_max; int32_t sctp_init_max_attempts; diff --git a/lib/src/asn1/liblte_mme.cc b/lib/src/asn1/liblte_mme.cc index cfde8de37f..48f3f9817a 100644 --- a/lib/src/asn1/liblte_mme.cc +++ b/lib/src/asn1/liblte_mme.cc @@ -3019,9 +3019,13 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_emergency_number_list_ie(uint8** emerg_num_list->N_emerg_nums = 0; while (length < sent_length) { idx = emerg_num_list->N_emerg_nums; + //add length check on emergency number list + if (idx >= LIBLTE_MME_EMERGENCY_NUMBER_LIST_MAX_SIZE) { + return (err); + } emerg_num_list->emerg_num[idx].N_emerg_num_digits = ((*ie_ptr)[length++] - 1) * 2; if (emerg_num_list->emerg_num[idx].N_emerg_num_digits > LIBLTE_MME_EMERGENCY_NUMBER_MAX_NUM_DIGITS) { - return err; + return (err); } emerg_num_list->emerg_num[idx].emerg_service_cat = diff --git a/lib/src/common/security.cc b/lib/src/common/security.cc index a5fb860d11..6449971eef 100644 --- a/lib/src/common/security.cc +++ b/lib/src/common/security.cc @@ -20,19 +20,13 @@ */ #include "srsran/common/security.h" +#include "mbedtls/md5.h" #include "srsran/common/liblte_security.h" #include "srsran/common/s3g.h" #include "srsran/common/ssl.h" #include "srsran/config.h" #include -#ifdef HAVE_MBEDTLS -#include "mbedtls/md5.h" -#endif -#ifdef HAVE_POLARSSL -#include "polarssl/md5.h" -#endif - #define FC_EPS_K_ASME_DERIVATION 0x10 #define FC_EPS_K_ENB_DERIVATION 0x11 #define FC_EPS_NH_DERIVATION 0x12 @@ -850,12 +844,7 @@ uint8_t security_128_eia3(const uint8_t* key, uint8_t security_md5(const uint8_t* input, size_t len, uint8_t* output) { memset(output, 0x00, 16); -#ifdef HAVE_MBEDTLS mbedtls_md5(input, len, output); -#endif // HAVE_MBEDTLS -#ifdef HAVE_POLARSSL - md5(input, len, output); -#endif return SRSRAN_SUCCESS; } diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index fe830507ba..5e8eb88a25 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -106,7 +106,7 @@ rx_gain = 40 # To use the dissector, edit the preferences for DLT_USER to # add an entry with DLT=150, Payload Protocol=s1ap. # -# mac_enable: Enable MAC layer packet captures (true/false) +# enable: Enable MAC layer packet captures (true/false) # filename: File path to use for LTE MAC packet captures # nr_filename: File path to use for NR MAC packet captures # s1ap_enable: Enable or disable the PCAP. @@ -387,6 +387,7 @@ nr_pdsch_mcs=28 # rlf_release_timer_ms: Time taken by eNB to release UE context after it detects a RLF # rlf_min_ul_snr_estim: SNR threshold in dB below which the enb is notified with RLF ko # s1_setup_max_retries: Maximum amount of retries to setup the S1AP connection. If this value is exceeded, an alarm is written to the log. -1 means infinity. +# s1_connect_timer: Connection Retry Timer for S1 connection (seconds) # rx_gain_offset: RX Gain offset to add to rx_gain to calibrate RSRP readings ##################################################################### [expert] @@ -423,5 +424,6 @@ nr_pdsch_mcs=28 #rlf_release_timer_ms = 4000 #rlf_min_ul_snr_estim = -2 #s1_setup_max_retries = -1 +#s1_connect_timer = 10 #rx_gain_offset = 62 #mac_prach_bi = 0 diff --git a/srsenb/hdr/stack/s1ap/s1ap.h b/srsenb/hdr/stack/s1ap/s1ap.h index 5414161fa3..39e9d52775 100644 --- a/srsenb/hdr/stack/s1ap/s1ap.h +++ b/srsenb/hdr/stack/s1ap/s1ap.h @@ -117,7 +117,7 @@ class s1ap : public s1ap_interface_rrc // Stack interface bool - handle_mme_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); + handle_mme_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); void start_pcap(srsran::s1ap_pcap* pcap_); private: @@ -272,7 +272,7 @@ class s1ap : public s1ap_interface_rrc bool was_uectxtrelease_requested() const { return release_requested; } void - set_state(s1ap_proc_id_t state, const erab_id_list& erabs_updated, const erab_item_list& erabs_failed_to_update); + set_state(s1ap_proc_id_t state, const erab_id_list& erabs_updated, const erab_item_list& erabs_failed_to_update); s1ap_proc_id_t get_state() const { return current_state; } ue_ctxt_t ctxt = {}; @@ -339,10 +339,14 @@ class s1ap : public s1ap_interface_rrc bool success = false; enum class cause_t { timeout, failure } cause; }; + struct s1connectresult { + bool success = false; + }; explicit s1_setup_proc_t(s1ap* s1ap_) : s1ap_ptr(s1ap_) {} srsran::proc_outcome_t init(); srsran::proc_outcome_t step() { return srsran::proc_outcome_t::yield; } + srsran::proc_outcome_t react(const s1connectresult& event); srsran::proc_outcome_t react(const s1setupresult& event); void then(const srsran::proc_state_t& result); const char* name() const { return "MME Connection"; } diff --git a/srsenb/hdr/stack/upper/rlc.h b/srsenb/hdr/stack/upper/rlc.h index 1fcd65665c..60d49d4fc8 100644 --- a/srsenb/hdr/stack/upper/rlc.h +++ b/srsenb/hdr/stack/upper/rlc.h @@ -56,7 +56,7 @@ class rlc : public rlc_interface_mac, public rlc_interface_rrc, public rlc_inter void clear_buffer(uint16_t rnti); void add_user(uint16_t rnti); void rem_user(uint16_t rnti); - void add_bearer(uint16_t rnti, uint32_t lcid, srsran::rlc_config_t cnfg); + void add_bearer(uint16_t rnti, uint32_t lcid, const srsran::rlc_config_t& cnfg); void add_bearer_mrb(uint16_t rnti, uint32_t lcid); void del_bearer(uint16_t rnti, uint32_t lcid); bool has_bearer(uint16_t rnti, uint32_t lcid); diff --git a/srsenb/sib.conf.example b/srsenb/sib.conf.example index c38cdbeb25..bafdcb689d 100644 --- a/srsenb/sib.conf.example +++ b/srsenb/sib.conf.example @@ -1,3 +1,12 @@ +##################################################################### +# sib1 configuration options (See TS 36.331) +# +# additional_plmns: A list of additional PLMN identities. +# mcc: MCC +# mnc: MNC +# cell_reserved_for_oper: One of "reserved" or "notReserved", default is "notReserved" +# +##################################################################### sib1 = { intra_freq_reselection = "Allowed"; diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index df348c2ce1..ac3a90b58f 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -79,6 +79,39 @@ bool sib_is_present(const sched_info_list_l& l, sib_type_e sib_num) return false; } +int field_additional_plmns::parse(libconfig::Setting& root) +{ + if (root.getLength() > ASN1_RRC_MAX_PLMN_MINUS1_R14) { + ERROR("PLMN-IdentityList cannot have more than %d entries", ASN1_RRC_MAX_PLMN_R11); + return SRSRAN_ERROR; + } + // Reserve the first place to the primary PLMN, see "SystemInformationBlockType1 field descriptions" in TS 36.331 + data->plmn_id_list.resize((uint32_t)root.getLength() + 1); + for (uint32_t i = 0; i < data->plmn_id_list.size() - 1; i++) { + std::string mcc_str, mnc_str; + if (!root[i].lookupValue("mcc", mcc_str)) { + ERROR("Missing field mcc in additional_plmn=%d\n", i); + return SRSRAN_ERROR; + } + + if (!root[i].lookupValue("mnc", mnc_str)) { + ERROR("Missing field mnc in additional_plmn=%d\n", i); + return SRSRAN_ERROR; + } + + srsran::plmn_id_t plmn; + if (plmn.from_string(mcc_str + mnc_str) == SRSRAN_ERROR) { + ERROR("Could not convert %s to a plmn_id in additional_plmn=%d", (mcc_str + mnc_str).c_str(), i); + return SRSRAN_ERROR; + } + srsran::to_asn1(&data->plmn_id_list[i + 1].plmn_id, plmn); + if (not parse_enum_by_str(data->plmn_id_list[i + 1].cell_reserved_for_oper, "cell_reserved_for_oper", root[i])) { + data->plmn_id_list[i + 1].cell_reserved_for_oper = plmn_id_info_s::cell_reserved_for_oper_e_::not_reserved; + } + } + return 0; +} + int field_sched_info::parse(libconfig::Setting& root) { data->sched_info_list.resize((uint32_t)root.getLength()); @@ -2170,6 +2203,13 @@ int parse_sib1(std::string filename, sib_type1_s* data) sib1.add_field(make_asn1_enum_number_parser("si_window_length", &data->si_win_len)); sib1.add_field(new parser::field("system_info_value_tag", &data->sys_info_value_tag)); + // additional_plmns subsection uses a custom field class + parser::section additional_plmns("additional_plmns"); + sib1.add_subsection(&additional_plmns); + bool dummy_bool = true; + additional_plmns.set_optional(&dummy_bool); + additional_plmns.add_field(new field_additional_plmns(&data->cell_access_related_info)); + // sched_info subsection uses a custom field class parser::section sched_info("sched_info"); sib1.add_subsection(&sched_info); @@ -2603,7 +2643,10 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co return SRSRAN_ERROR; } sib_type1_s::cell_access_related_info_s_* cell_access = &sib1->cell_access_related_info; - cell_access->plmn_id_list.resize(1); + // In case additional PLMNs were given, resizing will remove them + if (cell_access->plmn_id_list.size() == 0) { + cell_access->plmn_id_list.resize(1); + } srsran::plmn_id_t plmn; if (plmn.from_string(mcc_str + mnc_str) == SRSRAN_ERROR) { ERROR("Could not convert %s to a plmn_id", (mcc_str + mnc_str).c_str()); diff --git a/srsenb/src/enb_cfg_parser.h b/srsenb/src/enb_cfg_parser.h index f077530958..adbd4eb489 100644 --- a/srsenb/src/enb_cfg_parser.h +++ b/srsenb/src/enb_cfg_parser.h @@ -118,6 +118,17 @@ class nr_cell_list_section final : public parser::field_itf } // namespace rr_sections +class field_additional_plmns final : public parser::field_itf +{ +public: + explicit field_additional_plmns(asn1::rrc::sib_type1_s::cell_access_related_info_s_* data_) { data = data_; } + int parse(Setting& root) override; + const char* get_name() override { return "additional_plmns"; } + +private: + asn1::rrc::sib_type1_s::cell_access_related_info_s_* data; +}; + class field_sched_info final : public parser::field_itf { public: diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index baac499c08..336ee2b652 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -268,11 +268,12 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("expert.ts1_reloc_overall_timeout", bpo::value(&args->stack.s1ap.ts1_reloc_overall_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocOverall Expiry Timeout value in milliseconds.") ("expert.rlf_min_ul_snr_estim", bpo::value(&args->stack.mac.rlf_min_ul_snr_estim)->default_value(-2), "SNR threshold in dB below which the eNB is notified with rlf ko.") - ("expert.sctp_reuse_addr", bpo::value(&args->stack.s1ap.sctp_reuse_addr)->default_value(false), "Use SO_REUSE_ADDR on S1-C interface.") ("expert.max_s1_setup_retries", bpo::value(&args->stack.s1ap.max_s1_setup_retries)->default_value(-1), "Max S1 setup retries") + ("expert.s1_connect_timer", bpo::value(&args->stack.s1ap.s1_connect_timer)->default_value(10), "Connection Retry Timer for S1 connection (seconds)") + ("expert.sctp_reuse_addr", bpo::value(&args->stack.s1ap.sctp_reuse_addr)->default_value(false), "Use SO_REUSE_ADDR on S1-C interface.") ("expert.sctp_rto_max", bpo::value(&args->stack.s1ap.sctp_rto_max)->default_value(6000), "SCTP maximum RTO.") ("expert.sctp_init_max_attempts", bpo::value(&args->stack.s1ap.sctp_init_max_attempts)->default_value(3), "Maximum SCTP init attempts.") - ("expert.sctp_max_init_timeo)", bpo::value(&args->stack.s1ap.sctp_max_init_timeo)->default_value(5000), "Maximum SCTP init timeout.") + ("expert.sctp_max_init_timeo)", bpo::value(&args->stack.s1ap.sctp_max_init_timeo)->default_value(5000), "Maximum SCTP init timeout.") ("expert.rx_gain_offset", bpo::value(&args->phy.rx_gain_offset)->default_value(62), "RX Gain offset to add to rx_gain to calibrate RSRP readings") ("expert.mac_prach_bi", bpo::value(&args->stack.mac.prach_bi)->default_value(0), "Backoff Indicator to reduce contention in the PRACH channel") diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 8bdcf7a899..bc4f0f60f5 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -44,7 +44,8 @@ namespace srsenb { rrc::rrc(srsran::task_sched_handle task_sched_, enb_bearer_manager& manager_) : logger(srslog::fetch_basic_logger("RRC")), bearer_manager(manager_), task_sched(task_sched_), rx_pdu_queue(128) -{} +{ +} rrc::~rrc() {} diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index 4d3df43898..9ae4bd2e3e 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -164,7 +164,7 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn meas_cfg.meas_id_to_rem_list.resize(1); meas_cfg.meas_id_to_rem_list[0] = nr_meas_id; - // FIXME: use bearer manager to remove EUTRA DRB + // TODO: use bearer manager to remove EUTRA DRB conn_recfg->rr_cfg_ded.drb_to_release_list_present = true; conn_recfg->rr_cfg_ded.drb_to_release_list.resize(1); conn_recfg->rr_cfg_ded.drb_to_release_list[0] = 1; diff --git a/srsenb/src/stack/s1ap/s1ap.cc b/srsenb/src/stack/s1ap/s1ap.cc index 8fa6ead048..a68e65c83e 100644 --- a/srsenb/src/stack/s1ap/s1ap.cc +++ b/srsenb/src/stack/s1ap/s1ap.cc @@ -41,6 +41,7 @@ using srsran::uint32_to_uint8; #define procError(fmt, ...) s1ap_ptr->logger.error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) #define procWarning(fmt, ...) s1ap_ptr->logger.warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) #define procInfo(fmt, ...) s1ap_ptr->logger.info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define procDebug(fmt, ...) s1ap_ptr->logger.debug("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) #define WarnUnsupportFeature(cond, featurename) \ do { \ @@ -246,23 +247,41 @@ srsran::proc_outcome_t s1ap::s1_setup_proc_t::start_mme_connection() return srsran::proc_outcome_t::success; } - if (not s1ap_ptr->connect_mme()) { - procInfo("Could not connect to MME"); - return srsran::proc_outcome_t::error; - } + auto connect_callback = [this]() { + bool connected = s1ap_ptr->connect_mme(); - if (not s1ap_ptr->setup_s1()) { - procError("S1 setup failed. Exiting..."); - srsran::console("S1 setup failed\n"); - s1ap_ptr->running = false; - return srsran::proc_outcome_t::error; - } + auto notify_result = [this, connected]() { + s1_setup_proc_t::s1connectresult res; + res.success = connected; + s1ap_ptr->s1setup_proc.trigger(res); + }; + s1ap_ptr->task_sched.notify_background_task_result(notify_result); + }; + srsran::get_background_workers().push_task(connect_callback); + procDebug("Connection to MME requested."); - s1ap_ptr->s1setup_timeout.run(); - procInfo("S1SetupRequest sent. Waiting for response..."); return srsran::proc_outcome_t::yield; } +srsran::proc_outcome_t s1ap::s1_setup_proc_t::react(const srsenb::s1ap::s1_setup_proc_t::s1connectresult& event) +{ + if (event.success) { + procInfo("Connected to MME. Sending S1 setup request."); + s1ap_ptr->s1setup_timeout.run(); + if (not s1ap_ptr->setup_s1()) { + procError("S1 setup failed. Exiting..."); + srsran::console("S1 setup failed\n"); + s1ap_ptr->running = false; + return srsran::proc_outcome_t::error; + } + procInfo("S1 setup request sent. Waiting for response."); + return srsran::proc_outcome_t::yield; + } + + procInfo("Could not connected to MME. Aborting"); + return srsran::proc_outcome_t::error; +} + srsran::proc_outcome_t s1ap::s1_setup_proc_t::react(const srsenb::s1ap::s1_setup_proc_t::s1setupresult& event) { if (s1ap_ptr->s1setup_timeout.is_running()) { @@ -329,7 +348,7 @@ int s1ap::init(const s1ap_args_t& args_, rrc_interface_s1ap* rrc_) } s1setup_proc.launch(); }; - mme_connect_timer.set(10000, mme_connect_run); + mme_connect_timer.set(args.s1_connect_timer * 1000, mme_connect_run); // Setup S1Setup timeout s1setup_timeout = task_sched.get_unique_timer(); uint32_t s1setup_timeout_val = 5000; diff --git a/srsenb/src/stack/upper/rlc.cc b/srsenb/src/stack/upper/rlc.cc index 1b021ad05c..8611ec1059 100644 --- a/srsenb/src/stack/upper/rlc.cc +++ b/srsenb/src/stack/upper/rlc.cc @@ -112,7 +112,7 @@ void rlc::clear_buffer(uint16_t rnti) pthread_rwlock_unlock(&rwlock); } -void rlc::add_bearer(uint16_t rnti, uint32_t lcid, srsran::rlc_config_t cnfg) +void rlc::add_bearer(uint16_t rnti, uint32_t lcid, const srsran::rlc_config_t& cnfg) { pthread_rwlock_rdlock(&rwlock); if (users.count(rnti)) { diff --git a/srsenb/test/common/dummy_classes_common.h b/srsenb/test/common/dummy_classes_common.h index b3a2c8e124..b094cc1143 100644 --- a/srsenb/test/common/dummy_classes_common.h +++ b/srsenb/test/common/dummy_classes_common.h @@ -33,7 +33,7 @@ class rlc_dummy : public rlc_interface_rrc void clear_buffer(uint16_t rnti) override {} void add_user(uint16_t rnti) override {} void rem_user(uint16_t rnti) override {} - void add_bearer(uint16_t rnti, uint32_t lcid, srsran::rlc_config_t cnfg) override {} + void add_bearer(uint16_t rnti, uint32_t lcid, const srsran::rlc_config_t& cnfg) override {} void add_bearer_mrb(uint16_t rnti, uint32_t lcid) override {} void del_bearer(uint16_t rnti, uint32_t lcid) override {} void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) override { last_sdu = std::move(sdu); } diff --git a/srsenb/test/s1ap/s1ap_test.cc b/srsenb/test/s1ap/s1ap_test.cc index 359fdbd7be..9088fb3c13 100644 --- a/srsenb/test/s1ap/s1ap_test.cc +++ b/srsenb/test/s1ap/s1ap_test.cc @@ -141,8 +141,8 @@ void run_s1_setup(s1ap& s1ap_obj, mme_dummy& mme) sctp_sndrcvinfo rcvinfo = {}; int flags = 0; uint8_t s1_setup_resp[] = {0x20, 0x11, 0x00, 0x25, 0x00, 0x00, 0x03, 0x00, 0x3d, 0x40, 0x0a, 0x03, 0x80, 0x73, - 0x72, 0x73, 0x6d, 0x6d, 0x65, 0x30, 0x31, 0x00, 0x69, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0xf1, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x00, 0x57, 0x40, 0x01, 0xff}; + 0x72, 0x73, 0x6d, 0x6d, 0x65, 0x30, 0x31, 0x00, 0x69, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0xf1, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x00, 0x57, 0x40, 0x01, 0xff}; memcpy(sdu->msg, s1_setup_resp, sizeof(s1_setup_resp)); sdu->N_bytes = sizeof(s1_setup_resp); TESTASSERT(s1ap_obj.handle_mme_rx_msg(std::move(sdu), mme_addr, rcvinfo, flags)); @@ -173,16 +173,16 @@ void add_rnti(s1ap& s1ap_obj, mme_dummy& mme) sctp_sndrcvinfo rcvinfo = {}; int flags = 0; uint8_t icsr_msg[] = { - 0x00, 0x09, 0x00, 0x80, 0xac, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, - 0x00, 0x01, 0x00, 0x42, 0x00, 0x0a, 0x18, 0x3b, 0x9a, 0xca, 0x00, 0x60, 0x3b, 0x9a, 0xca, 0x00, 0x00, 0x18, - 0x00, 0x5e, 0x00, 0x00, 0x34, 0x00, 0x59, 0x45, 0x00, 0x09, 0x3c, 0x0f, 0x80, 0x7f, 0x00, 0x01, 0x64, 0x00, - 0x00, 0x00, 0x01, 0x4a, 0x27, 0x9b, 0x6d, 0xe9, 0x42, 0x01, 0x07, 0x42, 0x01, 0x3e, 0x06, 0x00, 0x00, 0xf1, - 0x10, 0x00, 0x07, 0x00, 0x1d, 0x52, 0x01, 0xc1, 0x01, 0x09, 0x07, 0x06, 0x73, 0x72, 0x73, 0x61, 0x70, 0x6e, - 0x05, 0x01, 0xc0, 0xa8, 0x0a, 0x02, 0x27, 0x08, 0x80, 0x00, 0x0d, 0x04, 0x08, 0x08, 0x08, 0x08, 0x50, 0x0b, - 0xf6, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x1a, 0x32, 0xdd, 0x59, 0x35, 0x13, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x23, - 0x05, 0xf4, 0x32, 0xdd, 0x59, 0x35, 0x00, 0x6b, 0x00, 0x05, 0x18, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x49, 0x00, - 0x20, 0x84, 0xa4, 0xea, 0x15, 0x55, 0xb3, 0xe0, 0xf4, 0x55, 0xbe, 0x1f, 0x41, 0x52, 0x92, 0xfc, 0x04, 0xd8, - 0x02, 0x38, 0x0d, 0xe0, 0x81, 0x29, 0xe1, 0xaa, 0xd7, 0xc4, 0x7b, 0x12, 0x95, 0x72, 0xbe}; + 0x00, 0x09, 0x00, 0x80, 0xac, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, + 0x00, 0x01, 0x00, 0x42, 0x00, 0x0a, 0x18, 0x3b, 0x9a, 0xca, 0x00, 0x60, 0x3b, 0x9a, 0xca, 0x00, 0x00, 0x18, + 0x00, 0x5e, 0x00, 0x00, 0x34, 0x00, 0x59, 0x45, 0x00, 0x09, 0x3c, 0x0f, 0x80, 0x7f, 0x00, 0x01, 0x64, 0x00, + 0x00, 0x00, 0x01, 0x4a, 0x27, 0x9b, 0x6d, 0xe9, 0x42, 0x01, 0x07, 0x42, 0x01, 0x3e, 0x06, 0x00, 0x00, 0xf1, + 0x10, 0x00, 0x07, 0x00, 0x1d, 0x52, 0x01, 0xc1, 0x01, 0x09, 0x07, 0x06, 0x73, 0x72, 0x73, 0x61, 0x70, 0x6e, + 0x05, 0x01, 0xc0, 0xa8, 0x0a, 0x02, 0x27, 0x08, 0x80, 0x00, 0x0d, 0x04, 0x08, 0x08, 0x08, 0x08, 0x50, 0x0b, + 0xf6, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x1a, 0x32, 0xdd, 0x59, 0x35, 0x13, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x23, + 0x05, 0xf4, 0x32, 0xdd, 0x59, 0x35, 0x00, 0x6b, 0x00, 0x05, 0x18, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x49, 0x00, + 0x20, 0x84, 0xa4, 0xea, 0x15, 0x55, 0xb3, 0xe0, 0xf4, 0x55, 0xbe, 0x1f, 0x41, 0x52, 0x92, 0xfc, 0x04, 0xd8, + 0x02, 0x38, 0x0d, 0xe0, 0x81, 0x29, 0xe1, 0xaa, 0xd7, 0xc4, 0x7b, 0x12, 0x95, 0x72, 0xbe}; sdu = srsran::make_byte_buffer(); memcpy(sdu->msg, icsr_msg, sizeof(icsr_msg)); sdu->N_bytes = sizeof(icsr_msg); @@ -234,6 +234,9 @@ void test_s1ap_erab_setup(test_event event) args.enb_name = "srsenb01"; TESTASSERT(s1ap_obj.init(args, &rrc) == SRSRAN_SUCCESS); + // The S1 Setup Procedure will call `notify_background_task_result` + // which we need to manually trigger with `run_next_task()` + task_sched.run_next_task(); run_s1_setup(s1ap_obj, mme); add_rnti(s1ap_obj, mme); diff --git a/srsgnb/src/stack/mac/mac_nr.cc b/srsgnb/src/stack/mac/mac_nr.cc index 3e30222e77..a60c5226b0 100644 --- a/srsgnb/src/stack/mac/mac_nr.cc +++ b/srsgnb/src/stack/mac/mac_nr.cc @@ -651,7 +651,7 @@ srsran::byte_buffer_t* mac_nr::assemble_rar(srsran::const_span& buffer, float rx_gain_offset) = 0; + virtual bool measure_rat(const measure_context_t& context, std::vector& buffer, float rx_gain_offset) = 0; /** * @brief Measurement process helper method. Encapsulates the neighbour cell measurement functionality diff --git a/srsue/hdr/phy/scell/intra_measure_lte.h b/srsue/hdr/phy/scell/intra_measure_lte.h index bf5d84360a..cfdcc5ef0e 100644 --- a/srsue/hdr/phy/scell/intra_measure_lte.h +++ b/srsue/hdr/phy/scell/intra_measure_lte.h @@ -79,7 +79,7 @@ class intra_measure_lte : public intra_measure_base * @param rx_gain_offset Provides last received rx_gain_offset * @return True if no error happens, otherwise false */ - bool measure_rat(measure_context_t context, std::vector& buffer, float rx_gain_offset) override; + bool measure_rat(const measure_context_t& context, std::vector& buffer, float rx_gain_offset) override; srslog::basic_logger& logger; srsran_cell_t serving_cell = {}; ///< Current serving cell in the EARFCN, to avoid reporting it diff --git a/srsue/hdr/phy/scell/intra_measure_nr.h b/srsue/hdr/phy/scell/intra_measure_nr.h index 07446527e9..6c94bb7600 100644 --- a/srsue/hdr/phy/scell/intra_measure_nr.h +++ b/srsue/hdr/phy/scell/intra_measure_nr.h @@ -118,7 +118,7 @@ class intra_measure_nr : public intra_measure_base * @param rx_gain_offset Provides last received rx_gain_offset * @return True if no error happen, otherwise false */ - bool measure_rat(measure_context_t context, std::vector& buffer, float rx_gain_offset) override; + bool measure_rat(const measure_context_t& context, std::vector& buffer, float rx_gain_offset) override; srslog::basic_logger& logger; uint32_t cc_idx = 0; diff --git a/srsue/hdr/stack/mac/mac.h b/srsue/hdr/stack/mac/mac.h index a562aa204a..00a2af8618 100644 --- a/srsue/hdr/stack/mac/mac.h +++ b/srsue/hdr/stack/mac/mac.h @@ -139,12 +139,12 @@ class mac : public mac_interface_phy_lte, /* Buffers for PCH reception (not included in DL HARQ) */ const static uint32_t pch_payload_buffer_sz = 8 * 1024; - srsran_softbuffer_rx_t pch_softbuffer; + srsran_softbuffer_rx_t pch_softbuffer = {}; uint8_t pch_payload_buffer[pch_payload_buffer_sz]; /* Buffers for MCH reception (not included in DL HARQ) */ const static uint32_t mch_payload_buffer_sz = SRSRAN_MAX_BUFFER_SIZE_BYTES; - srsran_softbuffer_rx_t mch_softbuffer; + srsran_softbuffer_rx_t mch_softbuffer = {}; uint8_t mch_payload_buffer[mch_payload_buffer_sz]; srsran::mch_pdu mch_msg; diff --git a/srsue/hdr/stack/rrc_nr/rrc_nr_procedures.h b/srsue/hdr/stack/rrc_nr/rrc_nr_procedures.h index d467d4a78e..d03529d7e9 100644 --- a/srsue/hdr/stack/rrc_nr/rrc_nr_procedures.h +++ b/srsue/hdr/stack/rrc_nr/rrc_nr_procedures.h @@ -90,9 +90,9 @@ class rrc_nr::connection_setup_proc { public: explicit connection_setup_proc(rrc_nr& parent_); - srsran::proc_outcome_t init(const asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg_, - const asn1::rrc_nr::cell_group_cfg_s cell_group_, - srsran::unique_byte_buffer_t dedicated_info_nas_); + srsran::proc_outcome_t init(const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg_, + const asn1::rrc_nr::cell_group_cfg_s& cell_group_, + srsran::unique_byte_buffer_t dedicated_info_nas_); srsran::proc_outcome_t step() { return srsran::proc_outcome_t::yield; } static const char* name() { return "Connection Setup"; } srsran::proc_outcome_t react(const bool& config_complete); diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index 3f87227a3b..da6d3ed5b8 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -177,12 +177,12 @@ class nas : public nas_interface_rrc, public srsran::timer_callback, public nas_ // Parsers void parse_attach_accept(uint32_t lcid, srsran::unique_byte_buffer_t pdu); - void parse_attach_reject(uint32_t lcid, srsran::unique_byte_buffer_t pdu); + void parse_attach_reject(uint32_t lcid, srsran::unique_byte_buffer_t pdu, const uint8_t sec_hdr_type); void parse_authentication_request(uint32_t lcid, srsran::unique_byte_buffer_t pdu, const uint8_t sec_hdr_type); void parse_authentication_reject(uint32_t lcid, srsran::unique_byte_buffer_t pdu); void parse_identity_request(srsran::unique_byte_buffer_t pdu, const uint8_t sec_hdr_type); void parse_security_mode_command(uint32_t lcid, srsran::unique_byte_buffer_t pdu); - void parse_service_reject(uint32_t lcid, srsran::unique_byte_buffer_t pdu); + void parse_service_reject(uint32_t lcid, srsran::unique_byte_buffer_t pdu, const uint8_t sec_hdr_type); void parse_esm_information_request(uint32_t lcid, srsran::unique_byte_buffer_t pdu); void parse_emm_information(uint32_t lcid, srsran::unique_byte_buffer_t pdu); void parse_detach_request(uint32_t lcid, srsran::unique_byte_buffer_t pdu); diff --git a/srsue/hdr/stack/upper/nas_5g_procedures.h b/srsue/hdr/stack/upper/nas_5g_procedures.h index 48dd1fd067..60716f75f7 100644 --- a/srsue/hdr/stack/upper/nas_5g_procedures.h +++ b/srsue/hdr/stack/upper/nas_5g_procedures.h @@ -57,7 +57,7 @@ class nas_5g::pdu_session_establishment_procedure { public: explicit pdu_session_establishment_procedure(nas_5g_interface_procedures* parent_nas_, srslog::basic_logger& logger_); - srsran::proc_outcome_t init(const uint16_t pdu_session_id, const pdu_session_cfg_t pdu_session); + srsran::proc_outcome_t init(const uint16_t pdu_session_id, const pdu_session_cfg_t& pdu_session); srsran::proc_outcome_t react(const srsran::nas_5g::pdu_session_establishment_accept_t& pdu_session_est_accept); srsran::proc_outcome_t react(const srsran::nas_5g::pdu_session_establishment_reject_t& pdu_session_est_reject); srsran::proc_outcome_t step(); diff --git a/srsue/src/phy/scell/intra_measure_lte.cc b/srsue/src/phy/scell/intra_measure_lte.cc index 2aba66f471..947216391c 100644 --- a/srsue/src/phy/scell/intra_measure_lte.cc +++ b/srsue/src/phy/scell/intra_measure_lte.cc @@ -59,7 +59,7 @@ void intra_measure_lte::set_primary_cell(uint32_t earfcn, srsran_cell_t cell) set_current_sf_len((uint32_t)SRSRAN_SF_LEN_PRB(cell.nof_prb)); } -bool intra_measure_lte::measure_rat(measure_context_t context, std::vector& buffer, float rx_gain_offset) +bool intra_measure_lte::measure_rat(const measure_context_t& context, std::vector& buffer, float rx_gain_offset) { std::set cells_to_measure = context.active_pci; diff --git a/srsue/src/phy/scell/intra_measure_nr.cc b/srsue/src/phy/scell/intra_measure_nr.cc index 9343c17f5d..f669de15b8 100644 --- a/srsue/src/phy/scell/intra_measure_nr.cc +++ b/srsue/src/phy/scell/intra_measure_nr.cc @@ -90,7 +90,7 @@ bool intra_measure_nr::set_config(const config_t& cfg) return true; } -bool intra_measure_nr::measure_rat(const measure_context_t context, std::vector& buffer, float rx_gain_offset) +bool intra_measure_nr::measure_rat(const measure_context_t& context, std::vector& buffer, float rx_gain_offset) { std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); diff --git a/srsue/src/stack/rrc_nr/rrc_nr_procedures.cc b/srsue/src/stack/rrc_nr/rrc_nr_procedures.cc index 6922994e7e..c576b39fd0 100644 --- a/srsue/src/stack/rrc_nr/rrc_nr_procedures.cc +++ b/srsue/src/stack/rrc_nr/rrc_nr_procedures.cc @@ -317,9 +317,9 @@ rrc_nr::connection_setup_proc::connection_setup_proc(srsue::rrc_nr& parent_) : rrc_handle(parent_), logger(srslog::fetch_basic_logger("RRC-NR")) {} -srsran::proc_outcome_t rrc_nr::connection_setup_proc::init(const asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg_, - const asn1::rrc_nr::cell_group_cfg_s cell_group_, - srsran::unique_byte_buffer_t dedicated_info_nas_) +srsran::proc_outcome_t rrc_nr::connection_setup_proc::init(const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg_, + const asn1::rrc_nr::cell_group_cfg_s& cell_group_, + srsran::unique_byte_buffer_t dedicated_info_nas_) { Info("Starting..."); diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index 9c0d61efff..c328ada513 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -134,7 +134,7 @@ void nas::run_tti() // Process PLMN selection ongoing procedures callbacks.run(); - // Transmit intiating messages if necessary + // Transmit initiating messages if necessary switch (state.get_state()) { case emm_state_t::state_t::deregistered: // TODO Make sure cell selection is finished after transitioning from another state (if required) @@ -491,8 +491,6 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) logger.error("Not handling NAS message with integrity check error"); return; } - case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT: - break; default: logger.error("Not handling NAS message with SEC_HDR_TYPE=%02X", sec_hdr_type); return; @@ -511,12 +509,9 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) { switch (msg_type) { case LIBLTE_MME_MSG_TYPE_IDENTITY_REQUEST: // special case for IMSI is checked in parse_identity_request() - case LIBLTE_MME_MSG_TYPE_EMM_INFORMATION: - case LIBLTE_MME_MSG_TYPE_EMM_STATUS: case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REQUEST: case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REJECT: case LIBLTE_MME_MSG_TYPE_ATTACH_REJECT: - case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: case LIBLTE_MME_MSG_TYPE_DETACH_ACCEPT: case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REJECT: case LIBLTE_MME_MSG_TYPE_SERVICE_REJECT: @@ -543,7 +538,7 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) parse_attach_accept(lcid, std::move(pdu)); break; case LIBLTE_MME_MSG_TYPE_ATTACH_REJECT: - parse_attach_reject(lcid, std::move(pdu)); + parse_attach_reject(lcid, std::move(pdu), sec_hdr_type); break; case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REQUEST: parse_authentication_request(lcid, std::move(pdu), sec_hdr_type); @@ -558,7 +553,7 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) parse_security_mode_command(lcid, std::move(pdu)); break; case LIBLTE_MME_MSG_TYPE_SERVICE_REJECT: - parse_service_reject(lcid, std::move(pdu)); + parse_service_reject(lcid, std::move(pdu), sec_hdr_type); break; case LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_REQUEST: parse_esm_information_request(lcid, std::move(pdu)); @@ -1027,7 +1022,7 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu) ctxt_base.rx_count++; } -void nas::parse_attach_reject(uint32_t lcid, unique_byte_buffer_t pdu) +void nas::parse_attach_reject(uint32_t lcid, unique_byte_buffer_t pdu, const uint8_t sec_hdr_type) { LIBLTE_MME_ATTACH_REJECT_MSG_STRUCT attach_rej; ZERO_OBJECT(attach_rej); @@ -1036,6 +1031,13 @@ void nas::parse_attach_reject(uint32_t lcid, unique_byte_buffer_t pdu) logger.warning("Received Attach Reject. Cause= %02X", attach_rej.emm_cause); srsran::console("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause); + // do not accept if the message is not protected when the EMM cause is #25 (TS 24.301 Sec. 4.4.4.2) + if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS && + attach_rej.emm_cause == LIBLTE_MME_EMM_CAUSE_NOT_AUTHORIZED_FOR_THIS_CSG) { + logger.error("Not handling NAS Attach Reject message with EMM cause #25 without integrity protection!"); + return; + } + // stop T3410 if (t3410.is_running()) { logger.debug("Stopping T3410"); @@ -1263,7 +1265,7 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) current_sec_hdr = LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED; } -void nas::parse_service_reject(uint32_t lcid, unique_byte_buffer_t pdu) +void nas::parse_service_reject(uint32_t lcid, unique_byte_buffer_t pdu, const uint8_t sec_hdr_type) { LIBLTE_MME_SERVICE_REJECT_MSG_STRUCT service_reject; if (liblte_mme_unpack_service_reject_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &service_reject)) { @@ -1272,6 +1274,14 @@ void nas::parse_service_reject(uint32_t lcid, unique_byte_buffer_t pdu) } srsran::console("Received service reject with EMM cause=0x%x.\n", service_reject.emm_cause); + + // do not accept if the message is not protected when the EMM cause is #25 (TS 24.301 Sec. 4.4.4.2) + if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS && + service_reject.emm_cause == LIBLTE_MME_EMM_CAUSE_NOT_AUTHORIZED_FOR_THIS_CSG) { + logger.error("Not handling NAS Service Reject message with EMM cause #25 without integrity protection!"); + return; + } + if (service_reject.t3446_present) { logger.info( "Received service reject with EMM cause=0x%x and t3446=%d", service_reject.emm_cause, service_reject.t3446); diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index f388aa112c..1f8ac1ec1b 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -117,7 +117,7 @@ void nas_5g::run_tti() // Process PLMN selection ongoing procedures callbacks.run(); - // Transmit intiating messages if necessary + // Transmit initiating messages if necessary switch (state.get_state()) { case mm5g_state_t::state_t::deregistered: // TODO Make sure cell selection is finished after transitioning from another state (if required) diff --git a/srsue/src/stack/upper/nas_5g_procedures.cc b/srsue/src/stack/upper/nas_5g_procedures.cc index 528d180128..0d388a18f5 100644 --- a/srsue/src/stack/upper/nas_5g_procedures.cc +++ b/srsue/src/stack/upper/nas_5g_procedures.cc @@ -51,8 +51,8 @@ nas_5g::pdu_session_establishment_procedure::pdu_session_establishment_procedure logger(logger_), parent_nas(parent_nas_) {} -srsran::proc_outcome_t nas_5g::pdu_session_establishment_procedure::init(const uint16_t pdu_session_id_, - const pdu_session_cfg_t pdu_session_cfg) +srsran::proc_outcome_t nas_5g::pdu_session_establishment_procedure::init(const uint16_t pdu_session_id_, + const pdu_session_cfg_t& pdu_session_cfg) { // Get PDU transaction identity transaction_identity = parent_nas->allocate_next_proc_trans_id();